Files
ZNJJ-api-server/README.md
T

129 lines
6.1 KiB
Markdown
Raw Normal View History

# AI 事故信息采集 API(LangGraph 迁移分支)
本分支把事故采集、拍照和信息核实从 FastGPT workflow 迁移到嵌入式 LangGraph。
文本四接口通过 `AGENT_BACKEND` 选择 FastGPT 或 LangGraph,HTTP schema 与 SSE 事件保持兼容。
迁移作业计划见 [docs/langgraph-backend-migration-plan.md](docs/langgraph-backend-migration-plan.md),
字段兼容约定见 [docs/assignment6-compat.md](docs/assignment6-compat.md)。
## 环境与安装
Python 3.11 使用 Conda 环境 `py3.11`(见 [AGENTS.md](AGENTS.md))。
```bash
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 示例:
```dotenv
AGENT_BACKEND=langgraph
AGENT_STORAGE=sqlite
AGENT_SQLITE_PATH=./data/agent.sqlite3
AGENT_DB_AUTO_MIGRATE=false
```
首次初始化和运行:
```bash
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](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](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`
只隐藏对外差量,不影响内部字段提交。
## 测试
```bash
conda run -n py3.11 python -m pytest -q
```
测试覆盖公共 schema、两后端适配、流式校验/取消、会话串行、字段别名、错误码与持久化恢复。
SQLite 集成测试使用临时真实文件;PostgreSQL 集成测试需要
`AGENT_TEST_POSTGRES_DSN` 指向隔离测试库。未配置时 PostgreSQL 用例会明确跳过。
两端都有直接退出子进程的恢复测试,不调用真实 LLM。
真实模型评测使用 `evals/run.py`,结果按每轮模型与代码版本单独保存,
历史轮次通过率不代替当前提交的业务验收。
## 目录结构
```text
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 管线仍有独立配置,不由本次数据库选择自动迁移。
- 未知字段写入、敏感字段访问边界等兼容事项继续按兼容清单处理。