DeerFlow 技能实战:通过 HTTP API 与 claude-to-deerflow Skill 驱动长时程智能体
DeerFlow 技能实战:通过 HTTP API 与 claude-to-deerflow Skill 驱动长时程智能体
本文围绕仓库中的 claude-to-deerflow 技能文档 展开,讲解如何让外部智能体(如 Claude Code)通过 HTTP API 与一个正在运行的 DeerFlow 实例交互:从 Nginx 统一代理的端口架构、三个环境变量约定,到创建线程、流式发送消息、解析 SSE 事件流的完整调用链,再到模型/技能/记忆/文件上传等 12 类操作的 curl 用法。读完后,你可以直接复用文档附带的 chat.sh 与 status.sh 脚本,将 DeerFlow 作为下游研究引擎进行委派。
一、技能定位与整体架构
该 Skill 的核心使命是:让另一个 Agent 平台通过 DeerFlow 的 HTTP API 完成消息发送、研究任务委派、状态检查、模型/技能/代理清单查询、记忆管理和文件上传。文档 SKILL.md 将 DeerFlow 描述为"基于 LangGraph 构建的 AI 智能体平台",通过编排子智能体完成研究、代码执行和网页浏览等任务。
DeerFlow 在 Nginx 反向代理之后暴露两个 API 面,这一架构在 docker/nginx/nginx.conf 中可以得到精确印证:
| Service | Direct Port | Via Proxy | Purpose |
|---|---|---|---|
| Gateway API | 8001 | $DEERFLOW_GATEWAY_URL | REST 端点与嵌入式 Agent 运行时 |
| LangGraph-compatible API | 8001 | $DEERFLOW_LANGGRAPH_URL | Agent 线程、运行、流式输出 |
从源码结构看,两个 API 面实际由同一个 Gateway 服务承载:nginx.conf 中 set $gateway_upstream gateway:8001,而 /api/langgraph/ 这个 location 通过 rewrite ^/api/langgraph/(.*) /api/$1 break 把 LangGraph 风格的路径改写后转发给 Gateway。也就是说:
- 直连部署:两个面都指向 Gateway 的 8001 端口;
- 代理部署:统一入口监听 2026 端口(
listen 2026 default_server),/api/langgraph/*与/api/models、/api/memory、/api/skills、/api/agents、/api/threads/*等路由全部转发到gateway:8001,其余请求交给前端。
值得注意的代理细节还包括:SSE 流式输出依赖 proxy_buffering off 与 X-Accel-Buffering no;针对长 prompt 请求,/api/langgraph/ location 设置了 client_max_body_size 20M 和 600 秒的三级超时;文件上传 location(^/api/threads/[^/]+/uploads)则放宽到 100M。这些配置解释了为什么技能文档把 http://localhost:2026 作为默认入口——它正是 nginx 统一代理的监听端口。
二、环境变量约定:发任何请求前先解析 URL
文档明确强调:"Read these env vars before making any request." 三个变量的含义与默认值如下:
| Variable | Default | Description |
|---|---|---|
DEERFLOW_URL | http://localhost:2026 | 统一代理基础 URL |
DEERFLOW_GATEWAY_URL | ${DEERFLOW_URL} | Gateway API 基址(models、skills、memory、uploads) |
DEERFLOW_LANGGRAPH_URL | ${DEERFLOW_URL}/api/langgraph | LangGraph API 基址(threads、runs) |
技能要求在做任何 API 调用前,按如下方式解析基址(这与 chat.sh 第 19–21 行的实现完全一致):
# Resolve base URLs from env (do this FIRST before any API call)
DEERFLOW_URL="${DEERFLOW_URL:-http://localhost:2026}"
DEERFLOW_GATEWAY_URL="${DEERFLOW_GATEWAY_URL:-$DEERFLOW_URL}"
DEERFLOW_LANGGRAPH_URL="${DEERFLOW_LANGGRAPH_URL:-$DEERFLOW_URL/api/langgraph}"
这条约定让同一份 curl 命令既能打本机 Docker 部署(2026 代理),也能指向远程主机或直连 8001 的部署,无需修改请求体。
三、12 类核心操作逐一拆解
1. 健康检查
curl -s "$DEERFLOW_GATEWAY_URL/health"
/health 是 nginx 显式配置的 Gateway 透传路由。chat.sh 中的实际做法更严格:用 curl -w "%{http_code}" 只取状态码,若为 000(不可达)或 ≥400 则直接退出并提示 cd <deerflow-dir> && make dev 启动实例。
2. 发送消息(流式)——主操作
这是整个技能的核心路径,分两步。
Step 1:创建线程
curl -s -X POST "$DEERFLOW_LANGGRAPH_URL/threads" \
-H "Content-Type: application/json" \
-d '{}'
响应:{"thread_id": "<uuid>", ...}。
Step 2:流式运行(Stream a run)
curl -s -N -X POST "$DEERFLOW_LANGGRAPH_URL/threads/<thread_id>/runs/stream" \
-H "Content-Type: application/json" \
\-d '{
"assistant_id": "lead_agent",
"input": {
"messages": [
{
"type": "human",
"content": [{"type": "text", "text": "YOUR MESSAGE HERE"}]
}
]
},
"stream_mode": ["values", "messages-tuple"],
"stream_subgraphs": true,
"config": {
"recursion_limit": 1000
},
"context": {
"thinking_enabled": true,
"is_plan_mode": true,
"subagent_enabled": true,
"thread_id": "<thread_id>"
}
}'
请求体各字段的含义可以结合源码确认:backend/app/gateway/run_models.py 中定义了 context 字段,描述为 "DeerFlow context overrides (model_name, thinking_enabled, etc.)",即 context 是 DeerFlow 专属的运行参数覆盖通道;backend/docs/API.md 进一步解释 thinking_enabled 用于为支持的模型开启扩展思考,is_plan_mode 用于启用 TodoList 中间件做任务跟踪。recursion_limit: 1000 则对应 LangGraph 的图递归上限,为长时程(数十分钟到数小时)的多轮工具调用留足空间。
SSE 事件格式与关键事件类型
响应是 SSE 流,每个事件形如:
event: <event_type>
data: <json_data>
关键事件:
metadata— 运行元数据,包含run_idvalues— 完整状态快照,含messages数组messages-tuple— 增量消息更新(AI 文本块、工具调用、工具结果)end— 流结束
四种上下文模式(Context modes)
通过 context 的三个布尔字段组合出四档强度,这是技能文档给出的核心调参表:
| 模式 | thinking_enabled | is_plan_mode | subagent_enabled | 适用场景 |
|---|---|---|---|---|
| Flash | false | false | false | 快速问答 |
| Standard | true | false | false | 常规对话 |
| Pro | true | true | false | 研究任务(脚本默认模式) |
| Ultra | true | true | true | 深度研究,启用子智能体 |
这些字段在 Gateway 侧是被显式白名单化处理的:backend/app/gateway/services.py 第 396–399 行附近将 thinking_enabled、is_plan_mode、subagent_enabled 等字段列入上下文字段集合,保证它们能从请求体透传到 Agent 运行时。backend/app/channels/manager.py 第 70–72 行的默认上下文为 thinking_enabled: True, is_plan_mode: False, subagent_enabled: False,可作为各字段缺省行为的参照。
3. 继续对话
复用 Step 2 中的同一个 thread_id,再次 POST 一个新的 run 即可,新消息会以 type: "human" 追加进该线程的消息历史。chat.sh 的第二参数正是为此设计:bash chat.sh "Your question" <thread_id> 表示续接已有会话。
4. 列出模型
curl -s "$DEERFLOW_GATEWAY_URL/api/models"
返回 {"models": [{"name": "...", "provider": "...", ...}, ...]}。该端点由 backend/app/gateway/routers/models.py 的 list_models 实现(GET /models,响应模型 ModelsListResponse),并从 AppConfig 读取可用模型配置。
5. 列出技能
curl -s "$DEERFLOW_GATEWAY_URL/api/skills"
返回 {"skills": [{"name": "...", "enabled": true, ...}, ...]}。
6. 启用/禁用技能
curl -s -X PUT "$DEERFLOW_GATEWAY_URL/api/skills/<skill_name>" \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
7. 列出 Agent
curl -s "$DEERFLOW_GATEWAY_URL/api/agents"
返回 {"agents": [{"name": "...", ...}, ...]}。值得注意的是,chat.sh 的流式请求固定使用 "assistant_id": "lead_agent",即把请求路由给 DeerFlow 的主智能体;/api/agents 可用于确认该 id 是否可用。
8. 获取记忆
curl -s "$DEERFLOW_GATEWAY_URL/api/memory"
返回用户上下文、事实(facts)与会话历史摘要,由 backend/app/gateway/routers/memory.py 提供。
9. 向线程上传文件
curl -s -X POST "$DEERFLOW_GATEWAY_URL/api/threads/<thread_id>/uploads" \
-F "files=@/path/to/file.pdf"
支持 PDF、PPTX、XLSX、DOCX,系统会自动转换为 Markdown 供 Agent 阅读。实现见 backend/app/gateway/routers/uploads.py 的 upload_files(POST,多文件 File(...) 字段,带 owner 权限检查 require_permission("threads", "write", owner_check=True))。
10. 列出已上传文件
curl -s "$DEERFLOW_GATEWAY_URL/api/threads/<thread_id>/uploads/list"
对应 uploads.py 中 GET /list 端点(list_uploaded_files),返回该线程 uploads 目录下的全部文件。
11. 获取线程历史
curl -s "$DEERFLOW_LANGGRAPH_URL/threads/<thread_id>/history"
12. 列出线程
curl -s -X POST "$DEERFLOW_LANGGRAPH_URL/threads/search" \
-H "Content-Type: application/json" \
-d '{"limit": 20, "sort_by": "updated_at", "sort_order": "desc"}'
注意这是一个 POST 搜索端点而非 GET 列表。status.sh 在此基础上加了 "select": ["thread_id", "updated_at", "values"] 字段投影,并用 Python 从 values.title 提取每个线程的标题,输出 thread_id / updated_at / title 三列摘要。
四、配套脚本:chat.sh 与 status.sh 的实现细节
chat.sh:一条命令完成"发消息 + 收全量回复"
bash /path/to/skills/claude-to-deerflow/scripts/chat.sh "Your question here"
完整用法(见脚本头部注释):
bash chat.sh "Your question here"
bash chat.sh "Your question" <thread_id> # 续接会话
bash chat.sh "Your question" "" pro # 指定模式
DEERFLOW_URL=http://host:2026 bash chat.sh "hi" # 自定义端点
模式参数支持 flash、standard、pro(默认)、ultra,与第二节的四档模式一一对应。脚本内部流程为:
- 健康检查:状态码非 2xx 即报错退出,提示用
make dev启动; - 创建或复用线程:未传
thread_id时 POST/threads,再用 Python 从响应中抽取thread_id; - 构造 context:按模式拼装三个布尔字段,并用
json.dumps转义用户消息避免 JSON 注入问题; - 流式拉取 + SSE 解析:
curl -N将完整 SSE 输出落盘到临时文件,随后内嵌的 Python 解析器处理事件流。
其中 SSE 解析逻辑值得单独看,它比文档"取最后一个 type: "ai" 消息"的简化描述更鲁棒:
- 事件重建:按行扫描,
event:行切换事件类型、data:行累积数据、空行落盘一个完整事件; - 响应抽取(
extract_response_text):从后往前遍历messages,优先识别ask_clarification中断——若遇到type: "tool"且name == "ask_clarification"的工具消息,直接返回其 content(即 Agent 在反问澄清,调用方应把该问题传回用户);否则取第一条非空type: "ai"消息,content 为字符串直接返回,为块列表则拼接其中所有type: "text"块; - 产物提取(
extract_artifacts):在最后一次响应周期(遇到human消息即停)内扫描 AI 消息的tool_calls,凡present_files调用就把args.filepaths收集为产物,并映射为 Gateway 产物 URL{gateway}/api/threads/{thread_id}/artifacts/{path}(虚拟路径如/mnt/user-data/outputs/file.md去掉前导斜杠); - 失败兜底:找不到 AI 响应时检查
error事件并打印 DeerFlow 错误;若原始 SSE 输出不足 2000 字符则整体打印,便于诊断。
status.sh:状态与资源盘点
bash status.sh # health + summary
bash status.sh models # 列出模型
bash status.sh skills # 列出技能
bash status.sh agents # 列出 agent
bash status.sh threads # 列出最近线程
bash status.sh memory # 显示记忆
bash status.sh thread <id> # 显示线程历史
其中 threads 子命令调用 POST /threads/search 并投影 values.title;thread <id> 子命令拉取 /history,对每个 state 只打印最近 5 条消息、每条截取 200 字符预览,是人工巡检会话进展的快捷方式。
五、SSE 输出的手动解析方法
如果不使用 chat.sh 而是自己处理流,文档给出的解析协议是:
- 定位最后一个
event: values块(前面可能有很多次状态快照,只有最后一次是最终态); - 解析其
data:行的 JSON; messages数组包含全部消息,最后一条type: "ai"即为回复;- 该消息的
content字段是 AI 的文本回复。
chat.sh 的 Python 解析器正是这一协议的参考实现,可直接借鉴其事件重建与 content 块拼接逻辑。
六、错误处理与实战建议
错误处理(源自 SKILL.md):
- 健康检查失败 → DeerFlow 未运行,告知用户需要先启动(
make dev或 Docker Compose); - 流中返回
error事件 → 提取并展示错误消息; - 常见问题:端口未开放、服务仍在启动中、配置错误。
实战 Tips:
- 快速问答用 flash 模式(最快,不做规划);
- 研究任务用 pro 或 ultra 模式(开启规划,ultra 额外启用子智能体);
- 可以先上传文件,再在消息中引用它们;
- Thread ID 持久化——之后随时可以回到同一会话继续对话。
七、适用前提与限制
- 默认端点
http://localhost:2026对应仓库 Docker/开发部署中 Nginx 统一代理(见 docker/nginx/nginx.conf 的listen 2026);若你的部署端口或路径不同,通过DEERFLOW_URL/DEERFLOW_GATEWAY_URL/DEERFLOW_LANGGRAPH_URL三个变量覆盖即可,请求体本身不需要改动; - 技能面向的是 LangGraph 兼容的 threads/runs 流式 API 与 Gateway 自定义 REST 端点两类路径,二者在代理模式下共用 2026 入口;
context中的thinking_enabled、is_plan_mode、subagent_enabled是否真正生效取决于所选模型与 Agent 配置(例如扩展思考只对支持该能力的模型有效),可用GET /api/models与GET /api/agents先行确认。
更多推荐
所有评论(0)