7.1 KiB
AI 问答上下文审计(2026-09-16)
范围:C:/kefu/wechat_rpa、C:/wechat_rpa 的桌面文本/视觉问答、共享模型协议及多模型/MCP 路由。此报告不代替主报告中的真实线上模型、知识检索服务端、视觉识别、原生协议测试结果。
已确认并修复
- 网关 Dify 请求丢弃历史和知识:
model_protocol.chat_payload()原来只取最后一条 user,system 中的已发布知识、客服规则以及此前问答全部丢失。新增dify_query(),按角色和顺序保留规则、知识、客户历史、客服历史、本轮问题和工具结果。单条 user 仍保持原请求格式;不复用跨客户 conversation_id。 - Dify 通用/裁判分支同样丢上下文:
ai_chat._chat_completion()的 Dify 兜底也只取最后 user,导致桌面 Dify 裁判可能缺少 system 中的评分和 JSON 格式要求。现复用同一协议转换。 - MCP 模型选择失效:显式选定模型进入 MCP 循环时没有传 provider,实际请求重新使用全局默认模型。现无工具、工具轮和最终回复均传递本轮选定 provider。
- 视觉请求污染检索文本:网关 customer_text 原来直接字符串化多模态 content,包含图片 base64。新增
message_text(content),仅抽取文本块;图片完整保留在 messages。可避免图片串进入知识查询/裁判文本。 - 历史轮数和损坏档案边界:本地轮数为字符串/非法值时抛 TypeError,0/负数会让裁剪失效;None 等损坏历史行抛 AttributeError。现轮数转为 1–50 整数,非法值回退 5,跳过非字典历史行。
- 两目录留痕差异:源目录缺少网关返回的 knowledge 留痕,目标目录已有。源目录现已同步保留该字段,便于验证知识使用情况。
上述代码修改仅涉及两个目录各自的 ai_chat.py、model_protocol.py;model_router.py 无需改动。原文件备份到各目录 backups/recognition-audit-20260916/ai-context/,修改前后 SHA-256 见 ai-context-manifest.json。
验证
新增 test_ai_context_audit.py 共 17 项。覆盖文本和视觉的 OpenAI/Claude/gateway 路由、Dify 直连文本和图片分支、Dify 共享协议和裁判协议、角色顺序、上下文关闭、最近轮数、非法配置、损坏历史、调用间隔离、不修改输入历史、图片不进入 customer_text、knowledge trace、MCP 指定模型及工具结果续传。
修复前先运行新增测试,16 项方法中的失败断言共 8 个、异常子场景共 4 个,证实上述问题不是仅凭代码推测。随后补上通用 Dify 裁判回归,总计 17 项。
最终用临时应用数据目录运行,阻止外网、真实鼠标键盘/截图和发送,仅允许测试自行创建的回环端口;运行结果:
| 目录 | 测试模块 | 通过 | 失败/异常/跳过 | 外部操作尝试 |
|---|---|---|---|---|
| C:/kefu/wechat_rpa | test_ai_context_audit、test_ai、test_model_router、test_agent_rules | 137 | 0/0/0 | 0 |
| C:/wechat_rpa | 同上 | 137 | 0/0/0 | 0 |
可复核文件:ai-context-source.json/.log、ai-context-target.json/.log。运行器为同目录 run_visual_audit.py。最初使用完全禁网运行器时,现有端口发现测试被错误拦截;改用允许测试回环连接的隔离器后通过,没有修改生产代码来绕过测试。
主任务另已得到真实线上印证:相同的合成多轮问题,Dify 上游未记住此前提供的信息,OpenAI 兼容出口能记住;这与修复前 Dify 只传最后 user 的实现一致。该真实调用由主任务执行,详情和修复后线上验证以主报告为准。
实际覆盖及限制
- 本报告证明上下文、知识文本和图片进入正确请求字段,不声称所有模型一定按要求作答。真实模型响应质量和线上部署状态另列。
- 历史按轮数裁剪,默认最近 5 轮、最多 50 轮;尚无针对不同模型 token 窗口的动态估算/摘要压缩,不能承诺任意长的单条历史都兼容。
- Dify/Claude 的原生工具调用转换不在现有实现范围。此次 MCP 回归验证 OpenAI/网关工具轮的选定模型、历史和工具结果续传,没有声称新增原生 Claude/Dify 工具支持。
- 账户/会话身份绑定发生在协议引擎和会话档案层,此处仅验证已传入某会话 history 的顺序、裁剪和调用间不泄漏;底层跨账户隔离由并行协议测试负责。
- 未连接真实微信、未向客户发送消息、未修改用户实际配置或业务数据库;已修改的生产文件仅为上列授权代码。
追加:网关 Dify 上传失败隔离复核
在主任务修复图片上传后,补充 test_gateway_failure_audit.py 10 项:纯文本不上传、exact 自定义路径、两图顺序/MIME/原始字节、上传与聊天 user 一致、旧轮图片不重传、内联/旧版重复图片去重、远程图片引用、上传 HTTP/网络/非 JSON/非对象错误不影响另一 OpenAI 出口。
修复前重现:上传响应为数组、字符串、数字时,.get() 引发 AttributeError,导致 asyncio.gather() 整体中断。只修改 model_gateway._dify_upload() 的响应结构校验,将不合法 JSON、非对象和无效 ID 转为出口级 GatewayError。原文件追加备份于 backups/recognition-audit-20260916/ai-context/model_gateway-before-upload-validation.py,哈希清单 gateway-upload-validation-manifest.json。
最终两目录各 10/10 通过,0 失败/异常/跳过;记录为 gateway-failure-source.json/.log 与 gateway-failure-target.json/.log。这部分是新增独立测试,不重复前面的 137 项。所有上传均由 httpx.MockTransport 接管。
追加:视觉守卫专用模型路由
新增 test_gateway_guard_audit.py 11 项,修复前端到端确认:purpose=guard 且配置 vision_id 时,网关仍调用答题 A、B 和客服裁判 J,完全没有调用专用视觉出口 V。这会使后台设置的视觉模型不生效,并额外增加调用和延迟。
已修复 Catalog.plan(purpose=...) 与 /v1/answer:guard 仅选可用 vision_id、明确不调用客服裁判;没有可用视觉角色的旧配置仅使用主答题出口兼容;专用视觉出口失败按该出口错误返回,不静默改用其他文本模型。普通聊天及普通图片问答保留原 answer_ids 并发/裁判行为。测试还覆盖 Dify 专用视觉模型接收上传截图、禁用/缺失/ComfyUI 视觉配置回退和仅有视觉角色的计划。
最后将 guard 11 项、上传失败 10 项与既有 test_model_gateway 32 项合并,两目录各 53/53 通过,0 失败/异常/跳过。记录 gateway-guard-source.json/.log、gateway-guard-target.json/.log;新增测试已同步两个项目。最终两个 model_gateway.py 字节一致,SHA-256:62f8367b3e4489feb829957cf46d95ff61fdfbbe3517c2511423c929349b68b2。
这一部分仍为隔离应用、临时数据库、模拟上游,线上是否使用修复版需由主任务实际部署/验证结果确认。最后变更清单为 gateway-guard-manifest.json;其前版本备份 model_gateway-before-guard-routing.py 保留此前已修的图片和上传校验逻辑。