deerflow-code/offline-backend-20260512/backend/docs/EXTERNAL_CHAT_SESSION_API_ZH.md
2026-09-07 18:24:55 +08:00

6.8 KiB
Raw Blame History

外部系统智能体会话与消息 API

Base URL 为 Gateway 的 /api(部署若由反向代理配置了前缀,以网关实际暴露地址为准)。所有接口沿用现有 Authorization: Bearer <token> 鉴权;无效或过期 token 返回 401。

会话隔离键

外部系统创建和检索会话时使用以下精确拼写的 metadata 键,三个值均为字符串:

键 类型 约定
agent_id string 智能体 ID
task_id string 任务 ID;数字也必须传字符串
chat_type string 页面决定的隔离标识;UTF-8 原样保存、原样比较、原样返回,不做 trim、大小写转换或枚举校验

chat_type 的可用长度大于 64 字符(metadata 存为 JSON 对象)。存量未带 chat_type 的线程保持原有行为;只有检索条件中显式提供 chat_type 时才会要求该字段精确相等。

1. 创建与按隔离键查找会话

POST /api/threads

参数 位置 必填 类型 说明
metadata.agent_id body 是(外部集成约定) string 智能体 ID
metadata.task_id body 是(外部集成约定) string 任务 ID
metadata.chat_type body 是(新会话) string 页面隔离键
thread_id body 否 string 不传则服务端生成 UUID
assistant_id body 否 string 现有兼容字段
{
  "metadata": {
    "agent_id": "c353429a73e146ae9e6926054b2d155a",
    "task_id": "108",
    "chat_type": "测试分析"
  }
}
{
  "thread_id": "c7cefe92-84f8-4f31-aed0-a16f7b151cc2",
  "status": "idle",
  "created_at": "2026-08-22T10:00:00+00:00",
  "updated_at": "2026-08-22T10:00:00+00:00",
  "metadata": {
    "agent_id": "c353429a73e146ae9e6926054b2d155a",
    "task_id": "108",
    "chat_type": "测试分析"
  },
  "values": {},
  "interrupts": {}
}

POST /api/threads/search

参数 位置 必填 类型 默认/范围 说明
metadata body 否 object {} 所有提供的键均做精确 AND 匹配
limit body 否 integer 100,1..1000 最多返回条数
offset body 否 integer 0,>=0 结果偏移量
{
  "metadata": {
    "agent_id": "c353429a73e146ae9e6926054b2d155a",
    "task_id": "108",
    "chat_type": "测试分析"
  },
  "limit": 1
}
[
  {
    "thread_id": "c7cefe92-84f8-4f31-aed0-a16f7b151cc2",
    "status": "idle",
    "created_at": "2026-08-22T10:00:00+00:00",
    "updated_at": "2026-08-22T10:05:10+00:00",
    "metadata": {
      "agent_id": "c353429a73e146ae9e6926054b2d155a",
      "task_id": "108",
      "chat_type": "测试分析"
    },
    "values": {},
    "interrupts": {}
  }
]

匹配结果按 updated_at 倒序,并以 thread_id 倒序作同时间稳定排序。响应返回完整 metadata。

2. 读取会话消息

GET /api/threads/{thread_id}/messages

参数 位置 必填 类型 默认/范围 说明
thread_id path 是 string - 会话 ID
limit query 否 integer 200,1..1000 返回消息数
offset query 否 integer 0,>=0 从最早消息起跳过的消息数

消息按照会话内实际写入顺序(时间正序)返回,total 为分页前总条数。接口读取最新 LangGraph checkpoint,并使用与 state/流式消息相同的序列化路径:不按展示用途裁剪 additional_kwargs、tool_calls、隐藏消息或供应商扩展字段。

{
  "total": 2,
  "messages": [
    {
      "type": "human",
      "id": "msg-1",
      "content": [{"type": "text", "text": "隐藏上下文"}],
      "additional_kwargs": {"hide_from_ui": true, "client_ts": "2026-08-22T18:00:00+08:00"}
    },
    {
      "type": "ai",
      "id": "msg-2",
      "content": "这是回答",
      "tool_calls": [{"name": "lookup", "args": {"keyword": "测试"}, "id": "call-1"}],
      "additional_kwargs": {"reasoning_content": "完整思考字段", "hide_from_ui": false}
    }
  ]
}

hide_from_ui 位于消息的 additional_kwargs.hide_from_ui(若该消息实际带有此字段)。tool_calls[].args 不被转换:LangChain 已解析的标准 tool_calls 通常是 JSON 对象;供应商原始工具调用若保留在 additional_kwargs,其原始字符串/对象形态也保持不变。

3. 删除一轮对话

DELETE /api/threads/{thread_id}/messages/{message_id}

message_id 应取自消息列表中用户消息(type: "human")的 id。删除该问题及其后的 AI、工具、中间消息,直到下一条用户消息之前;若传入的是非用户消息 ID,仅删除该消息。删除会写入新的 checkpoint,随后读取消息列表即可获得已删除后的结果。

成功示例:

{
  "ok": true,
  "deleted_ids": ["question-1", "answer-1", "tool-1"],
  "remaining": 2
}

4. 删除整个会话

DELETE /api/threads/{thread_id}

清理该线程的 checkpoint(含消息)、线程 metadata 与该线程目录下的上传文件/工作区/生成产物。会话检索不再返回该线程。

{"success": true, "message": "Deleted local thread data for c7cefe92-84f8-4f31-aed0-a16f7b151cc2"}

HTTP 错误

状态码 触发条件 响应体示例
401 缺少、无效或过期的 Bearer token {"detail":"Authentication required"}
403 token 没有对应线程权限 {"detail":"Permission denied: threads:read"}
404 线程不存在、无权访问、或 message_id 不存在 {"detail":"Thread xxx not found"}
409 上述接口当前不使用 409 不适用
422 分页参数越界,或请求体字段类型不合法 FastAPI 标准校验错误对象
429 上述接口本身未配置限流;如部署侧网关限流,由部署网关返回其配置的响应体 不适用
500 checkpoint 或持久化读取/写入失败 {"detail":"Failed to get thread messages"} 等

时间字段 created_at 与 updated_at 使用 ISO 8601、带 UTC 偏移量;不是毫秒时间戳。

兼容性与生命周期

  • 既有 /threads、/runs/stream、/models 调用不改动;仅新增消息查询,并修复单轮删除的 checkpoint 持久化。
  • 普通线程未配置通用自动过期策略、单任务会话数上限或 chat_type 枚举;保留至调用方删除或运维侧另行清理。AI 写作等独立业务的专用清理策略不适用于本接口。
  • 外部系统的联调 task、预置线程、发布窗口和联系人属于部署运维信息,不在代码中硬编码;请在目标测试环境创建后补入联调单。
  • Swagger 地址为 <Gateway Base URL>/docs;OpenAPI JSON 为 <Gateway Base URL>/openapi.json。