15 KiB
llm-in-text 生产环境修复清单
文档目的
本文档是针对当前仓库在 2026-04-01 状态下基于代码的生产就绪性审查。
它回答三个问题:
- 当前项目是否已准备好投入生产?
- 自上次审查以来已修复了哪些问题?
- 还有什么因素阻碍安全上线?
本次审查仅限于仓库中已有的内容和本地直接验证的内容,不包括外部基础设施、反向代理配置、云资源、CI 平台密钥或运行时运维的完整审计。
审查范围
- 前端构建和运行时入口
- 后端 FastAPI 端点和模型集成
- 补全、OCR 和文件转换请求路径
- 隐私相关行为和本地存储
- 基础测试覆盖率和构建验证
- PWA/Service Worker 状态
- 仓库中存在的部署和运维工件
已验证的事实
以下项目已针对当前仓库直接验证:
- 前端生产构建通过
npm.cmd run build成功 - 后端测试通过
pytest backend/tests -q - 当前后端测试结果:
8 passed, 1 skipped - 存在健康检查端点:
/health/live和/health/ready - 前端不再硬编码 API 密钥
- 后端不再需要旧的
X-API-Key头 - 前端隐私模式现在默认为启用
- 后端错误响应现在已规范化,不再返回原始异常字符串
- OCR 和转换端点现在强制执行基本的文件大小和扩展名检查
当前评估
项目尚未准备好投入生产。
当前状态更接近于:
- 一个可用的原型
- 内部演示
- 具有部分加固的预发布候选版本
由于缺少几个核心生产基线,它尚未准备好面向互联网的生产使用:
- 真正的限流和并发保护
- 正式的部署工件和运行时拓扑
- CI/CD 和自动化质量门禁
- 结构化的可观测性和告警
- 更强的请求验证和更安全的文件处理隔离
- 前端自动化测试和端到端验证
已修复的问题
与之前的清单相比,以下项目不再作为阻碍因素:
已修复:硬编码的前端/后端共享 API 密钥
src/utils/api.js不再发送X-API-Keysrc/utils/convert.js不再发送X-API-Keybackend/main.py不再强制执行旧的静态密钥
这消除了上次审查中最严重的问题之一。
遗留问题:
backend/tests/test_main_cancel.py仍然包含过时的X-API-Key头,但它们目前是无效的,表明测试假设已过时而非活动中的认证逻辑
已修复:危险的通配符 CORS 配置
当前后端 CORS 限制为:
http://localhost:5173http://localhost:3000
并使用:
allow_credentials=Falseallow_methods=["POST", "OPTIONS"]allow_headers=["Content-Type", "X-Request-Id"]
这比之前的通配符配置安全得多。
遗留问题:
- CORS 仍然针对本地开发硬编码,对于 staging/生产环境不是环境驱动的
已修复:默认收集前端公网 IP
src/stores/settings.js现在将privacyMode默认为truesrc/utils/api.js不再调用ipifysrc/utils/api.js不再发送X-Client-IPbackend/main.py不再将 IP 派生的位置注入提示词
遗留问题:
backend/geoip.py和 GeoLite 数据库仍然存在于仓库中,这可能会造成对当前隐私模型的混淆
已修复:向客户端暴露原始异常字符串
当前后端响应使用 _error_response(...) 和结构化载荷,例如:
INTERNAL_ERROROCR_FAILEDCONVERT_FAILEDFILE_TOO_LARGEINVALID_FILE_TYPE
这比直接返回 str(exception) 更好。
遗留问题:
- 日志仍然记录用户派生内容的预览,这是另一个隐私/可观测性问题
部分修复:上传和转换输入边界
backend/main.py 中的当前后端保护包括:
- OCR 大小上限:10 MB
- 转换大小上限:50 MB
- OCR 和转换的扩展名白名单
- 在
finally中清理临时转换文件
这是有意义的进展,但不足以投入生产。
生产阻碍因素
优先级含义:
P0:必须在生产上线前完成P1:应在公开发布或广泛推广前完成P2:重要的后续加固和维护工作
P0 阻碍因素
P0-01 声明了限流和并发控制但未强制执行
当前状态:
backend/main.py定义了MAX_CONCURRENT_COMPLETIONS = 4backend/main.py定义了COMPLETION_RATE_LIMIT = 60- 没有任何实际的限流器使用这两个值
- OCR 和转换端点也没有真正的每客户端节流
风险:
- 容易滥用昂贵的补全/OCR/转换端点
- 可避免地对模型主机、CPU、内存和临时存储造成过载
- 突发流量下无法控制降级
必需的修复:
- 在应用或网关中强制执行真正的每路由限流
- 为补全作业添加真正的并发保护
- 为
/v1/completions、/v1/ocr、/v1/convert添加单独预算 - 达到限制时返回明确的
429 - 为节流的请求和队列深度发出指标
验收标准:
- 重复的突发流量触发确定性的
429 - 并发补全不能超过配置的预算
- 负载测试下服务保持稳定
P0-02 仓库中不存在生产部署基线
当前状态:
- 后端仅通过
uvicorn.run(...)暴露开发式启动 - 没有
Dockerfile - 没有 compose 文件
- 没有 Kubernetes 清单或 Helm chart
- 没有 systemd 单元
- 没有反向代理参考配置
- 没有记录的生产环境契约
风险:
- 没有可复现的部署路径
- 没有明确的过程监督、重启或优雅的发布模型
- 没有记录的 ingress/请求体大小/超时/TLS 姿态
必需的修复:
- 定义一个官方部署目标
- 为该目标添加部署工件
- 记录所需的环境变量、端口、探针和存储
- 定义优雅关闭和发布行为
- 记录反向代理限制和信任边界
验收标准:
- 新环境可以从仓库文档和工件部署
- 健康探针已接入所选运行时
- 回滚路径已记录
P0-03 缺少 CI/CD 和仓库质量门禁
当前状态:
- 仓库级别没有找到
.github/workflows package.json没有真正的前端测试脚本- 没有 lint 脚本
- 没有类型检查脚本
- 没有依赖扫描或密钥扫描工作流
风险:
- 回归只能手动捕获
- 安全和打包漂移很可能发生
- 生产就绪性取决于本地开发者的规范
必需的修复:
- 为构建和测试添加 CI 工作流
- 添加前端自动化测试
- 在适用的情况下添加 lint 和类型检查门禁
- 添加依赖漏洞扫描
- 添加密钥扫描和基本 SAST
验收标准:
- 每个 PR 都运行构建、后端测试、前端测试和 lint
- 失败的检查阻止合并
P0-04 文件处理路径仍然缺乏生产级隔离
当前状态:
- 后端将完整 base64 载荷解码到内存中
- 转换写入临时文件并将其传递给
markitdown - OCR 和转换主要依赖扩展名检查,而不是内容嗅探
- 没有工作进程隔离或用于转换的单独沙箱
- 转换任务没有队列或资源预算
风险:
- 大型或并发上传导致内存峰值
- 畸形或对抗性文档会给解析器带来压力
- 转换工作负载可能干扰核心补全可用性
必需的修复:
- 明确验证 base64 解码失败
- 添加 MIME/内容嗅探,而不仅仅是扩展名检查
- 在入口和应用层添加更低的、路由特定的请求体限制
- 将转换隔离到单独的工作进程/进程边界
- 添加超时、并发上限和队列深度控制
验收标准:
- 畸形载荷失败并返回明确的 4xx 响应
- 转换不能饿死补全服务
- 压力下临时文件和内存增长保持有界
P0-05 环境配置不一致且不安全
当前状态:
- 前端
.env.example相当安全 - 后端
.env.example过时且与代码不一致 - 代码读取
OLLAMA_HOST - 后端示例仍然使用
OLLAMA_BASE_URL - 后端示例仍然定义
OPENAI_API_KEY=ollama,这是误导性的
风险:
- 新环境配置不正确
- 运营商可能假设不支持的认证/配置行为
- staging/生产漂移很可能发生
必需的修复:
- 用代码实际使用的变量替换后端环境示例
- 在启动时验证所需的环境变量
- 分离开发、staging 和生产环境契约
- 缺失关键配置时快速失败
验收标准:
- 示例环境文件匹配真实运行时行为
- 无效或缺失关键配置导致启动失败
P1 高优先级差距
P1-01 日志仍然捕获用户派生内容预览
当前状态:
backend/main.py记录提示词派生的前缀和后缀预览- 补全结果记录包含内容预览
- OCR 和转换记录文本预览长度和片段
风险:
- 日志可能包含敏感文档内容
- 隐私姿态与应用可见的隐私设置不一致
- 难以证明保留/合规姿态
必需的修复:
- 默认情况下停止记录用户内容正文和预览
- 仅保留请求元数据:路由、请求 ID、状态、延迟、大小
- 引入结构化 JSON 日志
- 脱敏或哈希任何敏感标识符
验收标准:
- 默认日志不包含用户文档文本
- 请求关联仍可通过请求 ID 和元数据工作
P1-02 请求验证仍然过于宽松
当前状态:
- Pydantic 模型定义了字段但没有长度或枚举约束
prefix、suffix、filename和reason受到极小约束- base64 字段在路由特定检查之前仍然可能非常大
- 前端转换路径在将完整文件读入 base64 之前不执行预验证
风险:
- 过大或畸形的请求太容易到达昂贵的逻辑
- 端点之间的 4xx 行为不一致
必需的修复:
- 为 Pydantic 字段添加长度和枚举约束
- 明确验证 base64 格式
- 更防御性地规范化文件名处理
- 添加前端预检查大小/类型作为 UX
验收标准:
- 畸形请求尽早失败并返回确定性的 4xx 响应
P1-03 前端自动化覆盖率基本缺失
当前状态:
- 后端有针对性的单元/集成风格测试
- 前端没有配置测试运行器
- 核心用户路径没有 E2E 覆盖率
重要说明:
backend/tests/test_main_cancel.py仍然发送过时的X-API-Key头;测试通过仅仅是因为后端忽略它们
风险:
- 编辑器、上传、OCR、转换和设置的回归将会遗漏
必需的修复:
- 添加前端单元/组件测试
- 为补全、取消、上传、OCR 和转换添加 E2E 覆盖率
- 从后端测试中移除过时的认证假设
验收标准:
- 核心用户旅程在 CI 中自动覆盖
P1-04 健康检查端点存在,但就绪性浅且缺少可观测性
当前状态:
/health/live存在/health/ready存在- 就绪性实际上不检查上游模型可用性
- 没有指标端点
- 没有追踪
- 没有告警定义
风险:
- 运行时故障检测太晚
- 平台探针可能报告健康而上游依赖不可用
必需的修复:
- 使就绪性反映关键依赖状态
- 添加请求/延迟/错误指标
- 为上游故障和饱和添加告警阈值
- 为关键路由定义仪表板
验收标准:
- 运营商可以快速检测模型依赖故障
- 请求成功率和延迟可观测
P1-05 Service Worker 实现存在但被禁用
当前状态:
public/sw.js存在src/main.js用&& false硬禁用注册- Service Worker 策略是手写的并通过静态缓存名称版本化
风险:
- 当前仓库包含未被实际使用的休眠 PWA 逻辑
- 如果随意重新启用,更新和缓存行为可能很脆弱
必需的修复:
- 确定 PWA 是否在生产范围内
- 如果是,采用维护的策略如 Vite PWA/Workbox
- 如果不是,移除无用的 Service Worker 代码以减少混淆
验收标准:
- PWA 行为要么被有意支持和测试,要么被完全移除
P1-06 背景图像持久化可能导致本地存储和内存膨胀
当前状态:
- 设置面板将上传的背景图像读取为 data URL
- 背景图像数据存储在 localStorage 中
- 没有对背景资产强制执行明确的大小上限
风险:
- 存储配额耗尽
- 大图像导致 UI 缓慢
- 跨浏览器的持久化行为脆弱
必需的修复:
- 读取前在客户端添加大小上限
- 持久化前调整大小/压缩
- 对于较大的资产,优先使用 blob/object URL 或 IndexedDB
- 为存储溢出添加迁移/错误处理
验收标准:
- 大图像不能降低启动或破坏设置持久化
P2 重要后续工作
P2-01 构建成功,但 bundle/chunk 策略仍然粗糙
验证的构建输出显示:
manualChunks生成许多空 chunk- 一个与 Mermaid 相关的大型 chunk 超过 1 MB 压缩后
风险:
- 不必要的 chunk 开销
- 较弱的设备上冷启动较慢
必需的修复:
- 简化
manualChunks - 延迟加载重型可选功能
- 清理 chunk 后重新测量首次加载成本
P2-02 OCR 缓存和图像哈希缓存没有明确的驱逐策略
当前状态:
- OCR 数据存储在内存中的
Map - 哈希缓存也在内存中
- 没有 TTL
- 没有最大条目数
风险:
- 长时间会话会累积内存
必需的修复:
- 添加 TTL 和条目边界
- 如需要,暴露缓存指标用于调试
P2-03 仓库仍然包含过时和混淆的工件
示例:
backend/geoip.py和 GeoLite DB 仍然存在,尽管 IP 地理定位在请求流程中不再活跃backend/.env.example记录的变量不是代码使用的- 后端测试仍然包含过时的
X-API-Key
风险:
- 未来维护者可能无意中重新引入已移除的行为
必需的修复:
- 移除死代码和过时配置
- 使测试和文档与当前实现保持一致
上线前必需的缺失证据
仓库目前不提供以下生产能力的证据:
- staging 部署管道
- 回滚程序
- 流量/负载测试结果
- 故障注入或混沌测试
- 备份/恢复程序
- 事件响应运行手册
- SLO/SLA 定义
- 安全扫描基线
- 依赖更新策略
- 隐私/数据保留文档
目前应将证据缺失视为未就绪,而不是隐式完成。
推荐的修复顺序
第一阶段:解除生产上线阻碍
- 实现真正的限流和并发强制执行
- 定义官方部署拓扑和工件
- 添加 CI/CD 质量门禁
- 加固和隔离文件处理工作负载
- 修复后端环境配置契约
第二阶段:稳定运维和隐私姿态
- 移除承载内容的日志
- 加强请求验证
- 深化就绪检查和指标
- 添加前端和 E2E 自动化测试
第三阶段:性能和可维护性清理
- 清理 chunk 策略
- 限制 OCR/图像缓存
- 移除过时代码和配置
- 决定 PWA 支持是保留还是移除
最低上线门槛
至少在以下所有条件都满足之前,不应称该项目为生产就绪:
- 所有
P0项目都已完成 - 日志不再捕获用户内容
- 前端和端到端自动化测试存在并在 CI 中运行
- 就绪性反映真实的上游依赖状态
- 部署和回滚已记录且可重现
- staging 环境已通过集成验证
- 至少执行了一次受控负载测试并经过审查
最终评估
与之前的清单相比,该项目已有实质性改进。几个严重的早期发现不再成立,特别是:
- 硬编码的认证密钥暴露
- 通配符式 CORS 姿态
- 默认公网 IP 收集
- 原始异常泄漏
然而,这一进展并不意味着已准备好投入生产。
当前仓库展示了有用的加固工作,但仍然缺乏生产服务预期的运维、测试、节流、部署和可观测性基线。