Files
kefu/deploy/recognition-audit-20260916/ai-context-report.md
T
2026-09-21 10:34:06 +08:00

58 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 问答上下文审计(2026-09-16)
范围:`C:/kefu/wechat_rpa`、`C:/wechat_rpa` 的桌面文本/视觉问答、共享模型协议及多模型/MCP 路由。此报告不代替主报告中的真实线上模型、知识检索服务端、视觉识别、原生协议测试结果。
## 已确认并修复
1. **网关 Dify 请求丢弃历史和知识**:`model_protocol.chat_payload()` 原来只取最后一条 user,system 中的已发布知识、客服规则以及此前问答全部丢失。新增 `dify_query()`,按角色和顺序保留规则、知识、客户历史、客服历史、本轮问题和工具结果。单条 user 仍保持原请求格式;不复用跨客户 conversation_id。
2. **Dify 通用/裁判分支同样丢上下文**:`ai_chat._chat_completion()` 的 Dify 兜底也只取最后 user,导致桌面 Dify 裁判可能缺少 system 中的评分和 JSON 格式要求。现复用同一协议转换。
3. **MCP 模型选择失效**:显式选定模型进入 MCP 循环时没有传 provider,实际请求重新使用全局默认模型。现无工具、工具轮和最终回复均传递本轮选定 provider。
4. **视觉请求污染检索文本**:网关 customer_text 原来直接字符串化多模态 content,包含图片 base64。新增 `message_text(content)`,仅抽取文本块;图片完整保留在 messages。可避免图片串进入知识查询/裁判文本。
5. **历史轮数和损坏档案边界**:本地轮数为字符串/非法值时抛 TypeError,0/负数会让裁剪失效;None 等损坏历史行抛 AttributeError。现轮数转为 1–50 整数,非法值回退 5,跳过非字典历史行。
6. **两目录留痕差异**:源目录缺少网关返回的 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 保留此前已修的图片和上传校验逻辑。