Files
ZNJJ-api-server/docs/assignment6-compat.md
T
Eric Wang 8717d9066c feat(services): assignment 6 skeleton - app service, field registry, in-memory repository
- fields_registry: 24 business keys in acd/human1/human2 groups with
  value_type, writable and SensitiveLevel metadata; strict bool/int
  parsing (no bool('0') trap); INTERNAL_FIELD_KEYS protection list
- repository: SessionRepository protocol + InMemorySessionRepository
  (idempotent delete; PostgreSQL swap-in is assignment 7)
- AccidentAppService: chat/set_info/get_info/delete_session share one
  business state - chat injects latest repository fields into the graph
  and writes back validated field diffs; set/get/delete make zero LLM
  calls and zero helper conversations (includeInputInfo accepted but
  unused); unknown get keys keep the '' JSON-empty-string contract,
  unknown set keys are rejected by whitelist
- ChatInput.injected_fields neutral contract extension; LangGraphBackend
  merges injected fields into graph input (set_info visible next chat)
- endpoints: thin layer - langgraph mode routes business state through
  the app service (fastgpt mode keeps the legacy path); delete cleans
  repository + graph checkpoint, idempotent
- tests: registry completeness (sfzmwh/sjwh/csbw included), app service
  combos with LLM-call spy, HTTP acceptance flow (set -> get -> chat ->
  groups -> delete -> no leak, idempotent re-delete)
- docs/assignment6-compat.md: behavior diff list vs FastGPT status quo
  and the audit backlog (arbitrary set_info key usage, stream formUpdate
  write-back, sensitive-field display boundary)

Verified: 200 unit tests (172 existing + 28 new)
2026-10-22 20:50:10 +08:00

2.9 KiB
Raw Blame History

作业 6 兼容差异清单:LangGraph 业务状态 vs FastGPT 现状

范围:/set_info、/get_info、/delete_session、/chat 四个接口在 AGENT_BACKEND=langgraph 下接入应用服务 + repository 后的行为差异。 FastGPT 模式(AGENT_BACKEND=fastgpt)保留旧实现,不受影响。

接口响应契约(保持不变)

项 现状(FastGPT) LangGraph(作业 6)
请求/响应模型 ProcessRequest/Response_* 相同(endpoint 未改模型)
get_info 分组名 all / acdinfo / acdhuman1 / acdhuman2 相同
get_info 布尔外部表示 True→"1",False→"0",未知→"" 相同(to_external_string)
get_info 未知 key 返回 JSON 空串 '""' 保持 '""'(现状兼容)
includeInputInfo 字段 触发 FastGPT 辅助对话 继续接受但忽略——新后端零辅助对话

有意的行为差异(新后端收紧)

项 FastGPT 现状 LangGraph 理由
set_info 未知 key 任意 key 写入 state 变量 拒绝(500 + "入参不规范:未知或受保护的字段 key") 白名单保护;任意写入会污染图输入。上线前需审计旧调用方是否依赖任意 key 写入
set_info 图内部键(stage_code 等) 可写(state 是裸 dict) 拒绝(INTERNAL_FIELD_KEYS 保护) 内部状态只允许图自己推进
set_info 字段值 任意字符串原样存 按注册表类型解析(bool/int 严格),无法解析拒绝 保留 空/False/0/未知 区分,杜绝 bool("0") 陷阱
LLM 调用 set/get 走辅助对话 + 事后删记录 零 LLM 调用(测试 spy 保证) 成本与延迟;删除 race 消失
重复 delete_session FastGPT SDK 行为未固定 幂等成功(业务状态 + checkpoint 均静默容忍缺失) 行为固定为测试

待审计项(作业 6-7 要求的后续工作)

  • 审计现有调用方是否存在对 set_info 任意 key 写入的依赖 (如动态自定义键)。存在则在注册表补登记或提供逃生口。
  • 流式 chat 的 formUpdate 差量写回 repository: 骨架阶段流式原样透传,差量写回仅在非流式 chat() 生效; 完整版随 FormUpdate 事件捕获补齐(见 app_service.stream 注释)。
  • get_info 返回值中的敏感字段(证件号/手机号)回显边界: 注册表已记录 SensitiveLevel,访问控制随作业 9 落地。

验证

  • test/services/test_fields_registry.py:注册表完整性、类型/敏感级别、 外部表示、bool("0") 防线。
  • test/services/test_app_service.py:四接口组合(set→get→chat 注入→ 差量写回→分组读→删除→无泄漏),set/get/delete 零模型调用 spy, 重复删除幂等。
  • test/api/test_assignment6_endpoints.py:HTTP 层验收演示链路。