17 KiB
任务分析定时 · 对外接口对接文档
面向外部任务系统(下称「对方系统」)的开发者。覆盖任务接入、时间线详情拉取、 总控问答、定时数据交付(任务 6 块 JSON)四组接口。智能体编排配置 (选业务链 / 执行频率)在 DeerFlow 任务分析页操作,对方系统无需开发。
相关实现:
app/gateway/routers/task_analysis.py(任务/绑定/运行记录)、app/gateway/routers/task_analysis_qa.py(问答)。
0. 通用约定
- Base URL:DeerFlow Gateway 地址(如
http://<host>:8001)。 - 鉴权:所有接口需带
Authorization: Bearer <token>请求头(token 获取方式见登录对接,本文不重复)。 - Content-Type:
application/json(SSE 接口除外,响应为text/event-stream)。 - 时间格式:ISO 8601 字符串(含时区,如
2026-09-10T10:14:55+08:00)。 - 两类任务标识:
source_task_id:对方系统的任务号(创建时由你们传入);task_id:DeerFlow 内部任务 id(创建接口的响应里返回,问答接口使用它)。 创建任务后请保存响应中的task_id;也可随时通过时间线详情接口重新取到。
1. 任务接入
1.1 创建任务
对方系统创建任务完成后调用,DeerFlow 落一条任务记录(初始未绑定分析方案)。
POST /api/task-analysis/external/tasks
请求体:
{
"source_task_id": "TS-2026-0147",
"name": "东南亚舆论环境监测",
"description": "持续跟踪东南亚重点渠道舆论动向,输出结构化分析详情。"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| source_task_id | string(≤128) | 是 | 对方任务号,全局唯一 |
| name | string(≤512) | 是 | 任务名称 |
| description | string(≤8192) | 否 | 任务简介。定时执行时注入各智能体的任务上下文以此为准(存量快照,执行时不会回拉) |
响应 200:
{
"task_id": "ta-TS-2026-0147",
"default_chain_id": "ta-demo-chain"
}
task_id:DeerFlow 内部任务 id,问答接口需要它,请保存。default_chain_id:DeerFlow 侧最近一次绑定使用的业务链 id,可作为你们界面上绑定流程的默认选项;无绑定为null。
错误:409 —— source_task_id 已存在。
1.2 删除任务
对方系统删除任务时同步调用,彻底删除:任务、绑定、全部执行记录、过程消息与时间线版本一并清除(不可恢复)。
DELETE /api/task-analysis/external/tasks/{source_task_id}
响应 200:{"deleted": true, "task_id": "..."}。错误:404 —— 任务不存在。
2. 任务详情(时间线)
对方系统详情页的数据源。每次定时执行成功会落一期时间线版本(含各智能体产出),按时间倒序返回。
GET /api/task-analysis/external/tasks/{source_task_id}/detail?limit=20&offset=0
响应 200:
{
"task": {
"task_id": "ta-TS-2026-0147",
"source_task_id": "TS-2026-0147",
"name": "东南亚舆论环境监测"
},
"binding": {
"chain_id": "ta-demo-chain",
"cron_expr": "0 9 * * *",
"schedule_type": "cron",
"enabled": true
},
"timeline": [
{
"id": "…",
"external_task_id": "ta-TS-2026-0147",
"run_id": "tar-…",
"blocks": {
"eightbf-roundtable-intent": {
"name": "8BF 任务理解",
"seat_agent_id": "eightbf-roundtable-intent",
"content": "(该智能体本次产出的 Markdown 正文)",
"format": "markdown"
},
"c0a8799da8724e179e086ea9ca723967": { "name": "策略分析师", "…": "…" }
},
"created_at": "2026-09-10T10:15:13+08:00"
}
]
}
binding:当前绑定信息(未绑定为null,此时timeline不会有新版本)。schedule_type为执行方式:cron= 按cron_expr频率定时执行;once= 只执行一次(创建后立即执行,之后不再自动执行,cron_expr不生效)。timeline[].blocks:每个参与执行的智能体一块,key 为该智能体的 agent_id,name为执行时的名称快照,content为其交付正文(Markdown)。 按你们的详情分区规则渲染即可(如按 block 顺序分栏)。- 分页:
limit(默认 20)/offset,按created_at倒序。
3. 总控问答(详情页对话)
详情页的对话入口:用户提问 → DeerFlow 总控按任务绑定的编排给对应智能体派活 → 智能体执行 → 总控汇总结论。一次问答会话记为一条「手动执行」记录,过程消息可查。
3.1 发起问答会话(init)
POST /api/task-analysis/tasks/{task_id}/qa/init
注意:此处
{task_id}为 DeerFlow 内部任务 id(创建接口响应里的task_id)。
请求体:空(无需参数)。
响应 200:
{
"run_id": "tar-0743654e-…",
"coordinator": "roundtable-coordinator",
"thread_ids": {
"eightbf-roundtable-intent": "ta-seat-…-…",
"c0a8799da8724e179e086ea9ca723967": "ta-seat-…-…",
"roundtable-coordinator": "ta-seat-…-…"
},
"seats": [
{ "agent_id": "eightbf-roundtable-intent", "name": "8BF 任务理解" },
{ "agent_id": "c0a8799da8724e179e086ea9ca723967", "name": "策略分析师" }
]
}
run_id:本次问答会话的运行记录 id(查历史 / 应用方向都用它)。thread_ids:会话线程映射,请保存并在后续每轮 stream 原样传回(会话不跨请求保存在服务端)。- init 时已自动把任务上下文(名称/简介/编排/历次方向备注)注入总控,之后每轮消息传用户原话即可。
错误:400 —— 任务未绑定分析方案 / 绑定链没有可调度席位。
3.2 发送消息(stream,SSE)
POST /api/task-analysis/tasks/{task_id}/qa/stream
Content-Type: application/json
Accept: text/event-stream
请求体:
{
"run_id": "tar-0743654e-…",
"message": "请让两个席位各自分析当前的主要风险点,然后给我综合结论。",
"thread_ids": { "…init 返回的映射原样传回…" }
}
响应为 SSE 流,每帧 data: {JSON}\n\n。帧类型:
| 帧 | 触发时机 | 关键字段 |
|---|---|---|
LangGraph 上游事件(无 event 字段的多种帧) |
总控正在生成(token 流) | 透传自运行时,可用于打字机效果 |
{"event": "leader", "status": [[seat_id, task], …], …} |
总控一轮结束 | status 为派活表(二维数组)时表示已派活 |
{"event": "leader", "status": "clarification", …} |
总控需要澄清 | question / options,前端展示追问,等用户补充后发下一轮 |
{"event": "leader", "status": [], "content": …} |
总控给出结论(共识) | content 为结论正文 |
{"event": "seat", "agent": id, "name": …, "content": …} |
某智能体执行完成 | content 为该智能体交付正文 |
{"event": "round_done", "consensus": true/false} |
本轮结束 | consensus=true 会话已收口(run 置 succeeded);false(如澄清)可继续发下一轮 |
一轮完整时序:leader(派活)→ 若干 seat(交付)→ leader(综合结论)→ round_done。
约定:
- 澄清(
consensus=false, kind=clarification):继续对同一 run_id 发下一轮 stream; - 共识(
consensus=true):run 已自动收口,如需再问请新开一次qa/init; - 客户端中断流不影响服务端继续执行(消息仍会落库,可从历史接口补读)。
错误:404 会话不存在;409 会话已收口(需重新 init)或 thread_ids 缺失(重新 init)。
3.3 应用调整方向(可选)
问答结束后,若用户确认「把本次调整应用到后续执行」,调用本接口把结论沉淀为 执行方向备注——该备注会注入此任务后续每次定时执行各智能体的任务上下文。
POST /api/task-analysis/qa/{run_id}/apply-direction
请求体:{"note": "后续执行请重点关注台湾海峡北段动态,风险输出按高/中/低分级。"}
响应 200:{"applied": true, "direction_notes": ["…", "…"]}(全部累计备注)。
3.4 对话历史查询
按运行记录查询完整过程消息(总控 + 各智能体),供会话回放或补读。
GET /api/task-analysis/external/runs/{run_id}/messages?seat=&limit=500
seat可选:传智能体 agent_id 只看该席位;传__coordinator__只看总控;不传看全部。- 响应:
{"run": {"id", "trigger", "status", "started_at", "finished_at"}, "messages": […]} - 消息字段:
seq(顺序)、seat_agent_id、stage_index、event_type(input输入 /llm.ai智能体输出 /artifact产物备注)、content。
4. 定时数据交付(任务 6 块数据)
按任务展示 6 块结构化数据(相当于 6 个页面分区,每块含多个部分),每块一个 JSON 对象。DeerFlow 只负责数据管道与调度:智能体在定时执行过程中把成果提交进 数据块,归配智能体 / 业务链的配置由管理方维护。
口径要点:
- 块 key 定死
block_1六」,可经 4.4 修改; 存量 5 块任务在读接口 / 首次提交时懒补block_6,标题默认「数据块一block_6,已改过的标题不覆盖; - payload 不做 schema 校验(结构会变),只要求是 JSON 对象;
- 不定席位↔块映射:多个智能体可各写一个块的不同部分,一个智能体也可写多个块;
- 同一块多次提交按「顶层 key 合并、同 key 后写覆盖」合并——某个部分一提交, 立刻体现在任务的当前数据里(实时更新);
- 不挂时间轴:一个任务的数据只有一份「当前状态」,所有提交(定时轮次、 手动触发、对话修复)都合并进它,越提交越新;
- 调度不管上一轮跑没跑完:到期照常触发,同任务允许多轮并行,不跳过不顺延; 多轮提交按流水顺序收敛到同一份数据;
- 首次提交时若任务还没有数据承载记录,自动创建一条(
trigger=external), 保证写入永远成功。
4.1 数据块定义列表
GET /api/task-analysis/external/tasks/{source_task_id}/blocks
响应 200:
{
"task": {"task_id": "ta-TS-2026-0147", "source_task_id": "TS-2026-0147", "name": "东南亚舆论环境监测"},
"blocks": [
{"block_key": "block_1", "title": "数据块一", "sort_order": 1},
{"block_key": "block_2", "title": "数据块二", "sort_order": 2},
{"block_key": "block_3", "title": "舆情热点", "sort_order": 3},
{"block_key": "block_4", "title": "数据块四", "sort_order": 4},
{"block_key": "block_5", "title": "数据块五", "sort_order": 5},
{"block_key": "block_6", "title": "数据块六", "sort_order": 6}
]
}
固定 6 条,按 sort_order 升序返回;title 为修改后的标题(见 4.4)。
4.2 当前数据状态(兼容旧路径 periods)
GET /api/task-analysis/external/tasks/{source_task_id}/periods
时间轴已去掉:任务的数据只有一份当前状态,本接口固定返回唯一一条当前数据
承载记录(periods 数组长度恒为 1,is_current 恒为 true),供消费方感知
数据更新时间。响应 200:
{
"task": {"task_id": "…", "source_task_id": "…", "name": "…"},
"current_period_index": 3,
"total": 1,
"periods": [
{
"period_index": 3,
"opened_at": "2026-09-14T15:00:00+08:00",
"trigger": "cron",
"run_id": "tar-…",
"is_current": true,
"blocks": {
"block_1": {"updated_at": "2026-09-14T15:03:12+08:00"},
"block_2": {"updated_at": null},
"block_3": {"updated_at": null},
"block_4": {"updated_at": null},
"block_5": {"updated_at": null},
"block_6": {"updated_at": null}
}
}
]
}
- 各块
updated_at为null表示该块尚无数据; - 首条承载记录由首次数据提交自动创建(
trigger=external);存量任务沿用 历史期号(period_index数值仅作标识,无时间轴含义)。
4.3 单期数据详情
GET /api/task-analysis/external/tasks/{source_task_id}/periods/{period}
{period} 传期号数字(如 2)或 latest(当前最新一期)。响应 200:
{
"task": {"task_id": "…", "source_task_id": "…", "name": "…"},
"period": {
"period_index": 2,
"opened_at": "2026-09-14T12:00:00+08:00",
"trigger": "cron",
"run_id": "tar-…",
"is_current": false
},
"blocks": [
{
"block_key": "block_1",
"title": "数据块一",
"sort_order": 1,
"payload": {"热点列表": ["…"], "统计": {"提及量": 128}},
"updated_at": "2026-09-14T12:04:55+08:00"
},
{"block_key": "block_2", "title": "数据块二", "sort_order": 2, "payload": null, "updated_at": null}
]
}
blocks固定 6 条、按sort_order升序;尚未提交的块payload/updated_at为null;payload即该块的合并结果(多次提交按顶层 key 合并、同 key 后写覆盖), 结构由智能体产出决定,请按 JSON 对象渲染;{period}推荐传latest(当前数据);传数字期号可访问存量任务的历史 遗留数据(时间轴去掉前的旧期,仅供排查)。
错误:404 —— 期不存在;400 —— period 既不是数字也不是 latest。
4.4 修改块标题 / 排序(管理端)
块标题支持后续修改(页面 + API)。{task_id} 为 DeerFlow 内部任务 id(创建
接口响应里保存的那个)。
PUT /api/task-analysis/tasks/{task_id}/blocks
请求体(只传要改的块;块集合固定 6 条,不能增删):
{
"blocks": [
{"block_key": "block_3", "title": "舆情热点"},
{"block_key": "block_1", "sort_order": 9}
]
}
响应 200:{"blocks": […]}(修改后的完整定义列表,形状同 4.1)。
错误:400 —— block_key 不在 block_1~block_6 内。
4.5 演示数据(已预存)
开发环境已预存一个演示任务,可直接用于联调:
- 任务号
source_task_id = BUSINESS-OVERVIEW-DEMO;block_1标题「商业态势总览」; - 预存时按 13 期小时刻度写入(时间轴去掉前的演示口径);当前对外仅暴露最新一期
的
block_1payload = 页面整卡数据(pageTitle/briefs/objectives/events/businessNarratives/insights/chart/snapshotName等, 与页面 mock 快照同构);block_2~block_6暂无数据; - 预存脚本:
scripts/seed_business_overview_demo.py(可重复运行,幂等重建)。
4.6 智能体数据提交(内部,供参考)
智能体侧由内置技能 task-data-submit(skills/public/task-data-submit/)调以下
接口完成入库,对方系统无需调用,此处仅供联调排查参考:
POST /api/task-analysis/data/submit
请求体:{"task_id": "<source_task_id>", "block_key": "block_2", "data": {…JSON 对象…}}。
响应 200:{"source_task_id", "task_id", "block_key", "period_index", "updated_at", "keys"}。
错误:400 —— 块 key 非法 / payload 不是对象;404 —— 任务不存在;422 ——
请求体不是合法 JSON 对象。
5. 典型对接流程
对方系统创建任务
└─ POST /external/tasks ──► 保存 task_id(+ default_chain_id)
│
│ (DeerFlow 管理页配置:选业务链 + 执行频率 —— 无需开发)
▼
按 cron 自动执行(多轮并行,产出时间线版本)
├─ 详情页定期/手动 GET /external/tasks/{source_task_id}/detail ──► 渲染 blocks
└─ 数据交付(任务 6 块 JSON,见第 4 章)
├─ GET /external/tasks/{source_task_id}/periods ──► 当前数据状态(兼容路径)
└─ GET /external/tasks/{source_task_id}/periods/latest ──► 6 块完整 JSON
│
▼
详情页问答(可选)
├─ POST /tasks/{task_id}/qa/init ──► 保存 run_id + thread_ids
├─ POST /tasks/{task_id}/qa/stream(每轮,SSE 渲染对话与席位交付)
├─ (可选)POST /qa/{run_id}/apply-direction ──► 调整注入后续执行
└─ GET /external/runs/{run_id}/messages ──► 历史回放
对方系统删除任务
└─ DELETE /external/tasks/{source_task_id} ──► DeerFlow 侧级联清除
6. 错误码汇总
| 状态 | 场景 |
|---|---|
| 400 | 任务未绑定分析方案 / 链无席位 / 请求参数非法 / 数据块 key 非法 |
| 401 | 未带 token 或 token 失效 |
| 404 | 任务 / 会话 / 运行记录 / 期不存在 |
| 409 | source_task_id 重复创建;会话已收口或线程映射缺失;执行被跳过(业务链已删除/停用) |