AI 事故信息采集 API(LangGraph 迁移分支)
本分支把事故采集、拍照和信息核实从 FastGPT workflow 迁移到嵌入式 LangGraph。
文本四接口通过 AGENT_BACKEND 选择 FastGPT 或 LangGraph,HTTP schema 与 SSE 事件保持兼容。
迁移作业计划见 docs/langgraph-backend-migration-plan.md,
字段兼容约定见 docs/assignment6-compat.md。
环境与安装
Python 3.11 使用 Conda 环境 py3.11(见 AGENTS.md)。
conda activate py3.11
pip install -r requirements.txt
# 项目仍使用该 SDK 支持 FastGPT 路径;源码在独立仓库维护。
pip install -e /path/to/fastgpt-python-sdk
配置与后端选择
复制 .env.example 为 .env 并填写配置;.env 不进入 Git。
- FastGPT:
AGENT_BACKEND=fastgpt,填写ANALYSIS_SERVICE_URL、ANALYSIS_AUTH_TOKEN、APP_ID。 - LangGraph:
AGENT_BACKEND=langgraph,按.env.example填写命名 LLM 配置, 由LLM_PROVIDER选择模型;文本后端不要求 FastGPT 凭证。 - LangGraph 存储:
AGENT_STORAGE=memory|sqlite|postgresql。每个实例只选一个,修改后重启。DATABASE_URL不控制 LangGraph 会话存储,切换数据库不自动搬迁旧数据。
本地 SQLite 示例:
AGENT_BACKEND=langgraph
AGENT_STORAGE=sqlite
AGENT_SQLITE_PATH=./data/agent.sqlite3
AGENT_DB_AUTO_MIGRATE=false
首次初始化和运行:
conda run -n py3.11 python -m src.storage.migrate --backend sqlite
conda run -n py3.11 python -m src.serve --port 8000
PostgreSQL 的连接池、迁移、本地 compose 与多 worker 部署见
docs/agent-storage.md。Windows 使用 python -m src.serve,
它为 psycopg 选择兼容的事件循环;Linux 也可用常规 uvicorn 命令启动。
模型调用
LangGraph 文本后端通过 langchain-openai.ChatOpenAI 调用 OpenAI 兼容接口。
现有 LLM_PROVIDERS / LLM_PROVIDER 和各组环境变量继续生效;统一使用
Chat Completions API,EXTRA_BODY 中的关闭推理等扩展参数照常透传。
依赖固定为 langchain-openai==1.1.9、langchain-core==1.5.1,
与当前 LangGraph 和 OpenAI SDK 环境配套验证。
应用层控制重试:默认每次尝试 60 秒、最多额外重试 3 次,退避 1/2/4 秒; 底层 SDK 自动重试关闭。模型文本开始输出后不重试,提前停止消费会显式关闭 底层 HTTP 流。兼容网关默认不请求流式 usage;非流式返回的 usage 可供 LangChain callbacks 使用。
模型调用继承图的 callbacks、metadata 和 tags,并标记 llm.complete / llm.stream
及 llm_attempt。这是追踪集成的基础,日志、存储和整轮 SSE 的观测需分别接入。
事故采集使用 LangGraph 原生并行分支:collect 生成回复,
extract_accident_fields 提取字段,二者经汇合边进入 merge_collect。
两个分支读取同一轮的参考时间和状态,各写独立通道,合并后统一提交。
人员核实的抽取依赖本轮回复,保持串行依赖。
增量输出由 LangChain 原生 astream_events(version="v2") 消费:
RunnableGenerator 输出通过阶段前缀校验的文本;validated_reply 的
on_chain_end 表示整条回复已通过校验,立即刷新分句器最后一句。
抽取模型的事件不转成聊天正文;formUpdate 和 done 仍等待业务提交成功。
客户端关闭流时由原生事件流取消并等待图任务,公开 SSE 事件类型不变。
节点职责、事件映射和提交时序见 docs/agent-streaming.md。
HTTP 接口
GET /:存活检查。POST /chat:对话;?stream=true使用真实增量 SSE。POST /set_info、POST /get_info:业务字段读写,不调用模型。DELETE /delete_session:清理 checkpoint 和业务状态,真实存储错误返回失败。- SQLite/PostgreSQL 模式可给
/chat添加Idempotency-Key请求头, 重放已提交结果;复用 key 但请求内容不同返回业务码 409。
SSE 的 error 是失败终止,done 是成功结束。正文可以先流出,
调用方必须在收到 done 后才将本轮视为成功。needFormUpdate=false
只隐藏对外差量,不影响内部字段提交。
测试
conda run -n py3.11 python -m pytest -q
测试覆盖公共 schema、两后端适配、流式校验/取消、会话串行、字段别名、错误码与持久化恢复。
SQLite 集成测试使用临时真实文件;PostgreSQL 集成测试需要
AGENT_TEST_POSTGRES_DSN 指向隔离测试库。未配置时 PostgreSQL 用例会明确跳过。
两端都有直接退出子进程的恢复测试,不调用真实 LLM。
真实模型评测使用 evals/run.py,结果按每轮模型与代码版本单独保存,
历史轮次通过率不代替当前提交的业务验收。
目录结构
src/
api/endpoints.py # HTTP schema、阶段标签解析、SSE 协议
agent/ # 流程图、节点、版本化提示词与模型服务
backends/ # FastGPT / LangGraph 中立适配
services/ # 四接口应用服务、字段注册表、会话锁
storage/ # SQLite / PostgreSQL、轮次日志、migration
core/fastgpt_client.py # 后端与存储生命周期、依赖注入
serve.py # 跨平台单 worker 启动入口
schemas/models.py # 公共请求/响应模型
test/storage/ # 两种数据库的真实集成与故障恢复测试
evals/ # 真实模型评测用例与 runner
部署边界
- memory 是临时存储,重启丢失;SQLite 限定单实例、单 worker。
- PostgreSQL 使用数据库级会话锁、版本和 epoch 校验;仍需按目标负载验证池容量与吞吐。
- 业务快照是已提交状态的权威源,旧 checkpoint 执行进度在下一轮重建, 不承诺从未提交的 LLM 调用中途续跑。
- 语音 WebSocket 管线仍有独立配置,不由本次数据库选择自动迁移。
- 未知字段写入、敏感字段访问边界等兼容事项继续按兼容清单处理。