Reconciled the field registry against workflow/20261022 (synced with main@c7ca781) and historical versions 20250419-20261021: - form six keys match the workflow form variable (bNJkeXot) and the 更新表单 whitelist semantics exactly - acd business keys originate from the 20250419 extraction schema (dropped by the workflow since 20251015, kept as the API contract) - person group keys (xm1/sfzmwh1/sjwh1/csbw1...) exist in no workflow version - they are the API server's own contract - the form<->business key mapping is migration-new semantics bridging both sides, fixed by bidirectional tests Finding: workflow 20261022 state uses driver1ID/driver1License/ driver1Phonenumber naming, which never matched the API get_info group keys - existing behavior read empty; recorded in the audit backlog to confirm which naming live callers actually use
87 lines
6.0 KiB
Markdown
87 lines
6.0 KiB
Markdown
# 作业 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")` 陷阱 |
|
||
| 图表单键与业务键 | FastGPT state 为裸 dict,无映射概念 | 建立双向映射(作业 6):表单六键(`has_injury` 等)<-> acd 业务键(`ywrysw` 等);`bjrjs`/`ywmtc` 无表单来源,仅 `set_info` 可写 | 图的表单语义与 get_info 业务分组需要同一份事实 |
|
||
| LLM 调用 | set/get 走辅助对话 + 事后删记录 | **零 LLM 调用**(测试 spy 保证) | 成本与延迟;删除 race 消失 |
|
||
| 重复 `delete_session` | FastGPT SDK 行为未固定 | **幂等成功**(业务状态删除天然幂等;checkpoint 清理重复触发但缺失静默容忍) | 行为固定为测试 |
|
||
|
||
## 图表单键 <-> 业务键映射(作业 6 建立)
|
||
|
||
| 图表单键(accident_fields) | 业务键(acdinfo 分组) |
|
||
|---|---|
|
||
| `has_injury` | `ywrysw` |
|
||
| `has_non_motor_vehicle_hit` | `ywfjdc` |
|
||
| `is_on_scene` | `sfsgxc` |
|
||
| `vehicle_count` | `jdcsl` |
|
||
| `accident_time` | `sgfssj` |
|
||
| `accident_cause` | `sgyy` |
|
||
|
||
- chat 方向:repository 业务键经映射注入图为表单键(图只认表单语义)。
|
||
- 写回方向:图产出的表单键差量经映射落 repository 业务键,get_info 分组即可读到。
|
||
- `bjrjs`(报警人是否驾驶员)、`ywmtc`(是否撞摩托车)无表单来源:
|
||
不进入注入映射,仅支持 set_info 直写、get_info 直读。
|
||
|
||
## 与 workflow 20261022 的字段对账(2026-10-22 核对)
|
||
|
||
核对来源:`workflow/20261022/事故信息采集2025118.json`(已与 main@c7ca781 同步)
|
||
及历史版本 20250419—20261021。
|
||
|
||
| 注册表内容 | 对账结果 |
|
||
|---|---|
|
||
| 图表单六键(`has_injury` 等,FORM_FIELDS 白名单) | **一致**。workflow `form` 全局变量(bNJkeXot)初始即这六键;「更新表单」code 节点白名单语义(只遍历表单已有字段、无效值/同值筛除)与本服务 `_merge_form` 相同 |
|
||
| acd 业务八键(`ywrysw` 等) | **语义一致,出处不同**。八键全部出自 **20250419 版** workflow 的提取 schema(含 `sgyy` 事故原因);20251015 起 workflow 已弃用,API 代码自 a1a4bce 起沿用为对外契约。新后端注册表保留 = 兼容旧契约 |
|
||
| 人员分组键(`xm1/sfzmhm1/sfzmwh1/sjwh1/csbw1` 等每组 8 键) | **任何 workflow 版本都不存在**。系 API 服务端自定义契约(get_info 分组)。`sfzmwh/sjwh/csbw` 的全量覆盖是契约要求,与 workflow 无关 |
|
||
| 作业 6 表单键<->业务键映射(`has_injury`->`ywrysw` 等) | workflow 中**无此映射**——两侧键名从未在同一系统共存(workflow 只用表单键,API 只用业务键)。映射是迁移时按中文语义建立的桥(对照 20250419 提取 schema 的 desc 字段),属本服务新增语义,已双向测试固定 |
|
||
|
||
### 对账发现的一个真实差异
|
||
|
||
20261022 workflow 的 `state` 变量中人员信息键为
|
||
`driver1ID / driver1License / driver1Phonenumber`(×2),
|
||
与 API `get_info` 分组键(`sfzmhm1/sjwh1/sjhm1` 等)**不同名**。
|
||
旧 FastGPT 实现按 API 分组键读 state,这些键在 workflow state 中
|
||
本就读空——属于既有行为。新后端注册表沿用了 API 契约键
|
||
(保证 get/set_info 自洽),workflow 侧键名差异已列入审计:
|
||
若线上有调用方依赖 `driver1ID` 等键,需决定是否补登记别名。
|
||
|
||
## 待审计项(作业 6-7 要求的后续工作)
|
||
|
||
- [ ] 审计现有调用方是否存在对 `set_info` 任意 key 写入的依赖
|
||
(如动态自定义键)。存在则在注册表补登记或提供逃生口。
|
||
**对账新增**:workflow 20261022 state 人员键
|
||
(`driver1ID`/`driver1License`/`driver1Phonenumber` ×2)
|
||
与 API 分组键不同名——确认线上调用方实际使用哪套键名,
|
||
必要时注册表补别名。
|
||
- [x] ~~流式 `chat` 的 `formUpdate` 差量写回 repository~~
|
||
(完整版已实现: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 层验收演示链路。
|