# 兼容 API 契约基线 ## 通用约定 - 路径保持 `/chat`、`/set_info`、`/get_info`。 - 请求和响应字段保持 camelCase。 - 业务成功/失败主要通过响应体字符串 `code` 表达;现有 endpoint 通常仍返回 HTTP 200。 - `sessionId` 最大 64 字符,`timeStamp` 最大 32 字符。 - Pydantic 校验失败由 FastAPI 返回 HTTP 422。 - 本文冻结的是当前可观察行为;“目标行为”标记为后续迁移必须修复的已批准偏差。 ## `POST /chat` ### 请求 | 字段 | 类型 | 必填 | 默认值 | |---|---|---:|---| | `sessionId` | string | 是 | - | | `timeStamp` | string | 是 | - | | `text` | string | 是 | - | | `needFormUpdate` | boolean | 否 | `false` | | `useTextChunk` | boolean | 否 | `false` | ### 非流式响应 字段为 `sessionId`、`timeStamp`、`outputText`、`formUpdate`、`nextStage`、`nextStageCode`、`code`、`msg`。 - 成功时 `code="200"`。 - `XXXX` 从正文中移除。 - `3001/3002/1002 → 1002`,`2006 → 2004`,`2017 → 2016`,`2020 → 0002`。 - Prefix 缺失或正文不可解析时当前返回 `code="500"` 和“消息不完整”。 - FastGPT 认证、限流和 API 异常分别映射为响应体 `401`、`429`、`500`。 - `formUpdate` 保持无固定 schema 的 JSON 值,以兼容现有调用方。 ### SSE 响应 事件名和数据: | 事件 | 数据 | 基数 | |---|---|---| | `stage_code` | `{"nextStageCode":"1002","nextStage":"通话中"}` | 成功轮最多一次 | | `formUpdate` | 表单 patch 对象 | 有更新时最多一次 | | `text_delta` | `{"text":"..."}` | 零到多次 | | `done` | `{"status":"completed"}` | 成功恰好一次 | | `error` | `{"msg":"...","code":"500"}` | 失败恰好一次且终止 | V1.0.9 文档要求 `stage_code` 先于 `text_delta`;`formUpdate` 的位置由 FastGPT `flowResponses` 到达时间决定,文档示例允许它出现在两个 `text_delta` 之间。LangGraph 迁移目标固定为: ```text stage_code -> formUpdate(可选) -> text_delta* -> done ``` 迁移后的错误路径不得同时产生 `done` 和 `error`。`useTextChunk=true` 只改变 `text_delta` 切分,不改变拼接后的文本。 ### 已知偏差 - 当前流式 parser 会在整段文本中搜索标签,而不是强制标签位于开头。 - 当前流式未知状态码仍可能发送空 `nextStage`。 - 当前流式缺少 prefix 时仍可能输出正文和 `done`。 - 当前流式内部事件处理异常会记录后继续,可能掩盖部分失败。 - 当前实现记录完整输入、输出和 `formUpdate`,不符合数据保护目标。 以上偏差被字符化测试记录,但不作为 LangGraph 新实现的目标行为;Phase 5–8 必须按迁移计划修正。 ## `POST /set_info` ### 请求 字段为 `sessionId`、`timeStamp`、`key`、`value`、`includeInputInfo`;其中 `includeInputInfo` 默认 `false`。 当前实现: 1. 通过一次 FastGPT 对话读取 `newVariables.state`; 2. 删除辅助对话记录; 3. 直接执行 `state[key] = value`; 4. 再通过 FastGPT 对话写回并删除辅助记录。 成功返回 `code="200"`;任一步失败返回响应体 `code="500"`。 目标行为: - 仅接受 `field-registry.json` 中 `external_write=true` 的 key。 - 进行类型转换和领域校验。 - 禁止写内部状态字段。 - 直接事务化写业务状态,不调用 LLM,不创建/删除辅助聊天记录。 ## `POST /get_info` 请求字段为 `sessionId`、`timeStamp`、`key`、`includeInputInfo`;`includeInputInfo` 默认 `false`。 支持: - `all` - `acdinfo` - `acdhuman1` - `acdhuman2` - 单个字段 key 兼容序列化: - `value` 始终是 JSON 编码后的字符串。 - boolean 转为字符串 `"1"` 或 `"0"`。 - 缺失字段转为空字符串。 - 未知单字段 key 当前返回 JSON 字符串 `""`,而不是报错。 目标实现仍保留上述响应编码,但直接读取业务投影,不调用 FastGPT。 ## 契约来源 - `src/schemas/models.py` - `src/api/endpoints.py` - `docs/视频快处智能信息采集机器人交互接口文档V1.0.9.docx` - `docs/chat-stream-mode.md` - `test/api/test_public_schema_contract.py` - `test/api/test_chat_backend_boundary.py`