- 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)
2.9 KiB
2.9 KiB
作业 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 层验收演示链路。