mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-05-23 00:16:48 +00:00
docs: complete all English and Chinese documentation pages
Agent-Logs-Url: https://github.com/bytedance/deer-flow/sessions/a5f192e7-8034-4e46-af22-60b90ee27d40 Co-authored-by: foreleven <4785594+foreleven@users.noreply.github.com>
This commit is contained in:
committed by
JeffJiang
parent
716cae20c6
commit
814a488bcb
@@ -4,6 +4,21 @@ const meta: MetaRecord = {
|
||||
index: {
|
||||
title: "概览",
|
||||
},
|
||||
introduction: {
|
||||
title: "简介",
|
||||
},
|
||||
harness: {
|
||||
title: "DeerFlow Harness",
|
||||
},
|
||||
application: {
|
||||
title: "DeerFlow 应用",
|
||||
},
|
||||
tutorials: {
|
||||
title: "教程",
|
||||
},
|
||||
reference: {
|
||||
title: "参考",
|
||||
},
|
||||
workspace: {
|
||||
type: "page",
|
||||
},
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { MetaRecord } from "nextra";
|
||||
|
||||
const meta: MetaRecord = {
|
||||
index: {
|
||||
title: "概览",
|
||||
},
|
||||
"quick-start": {
|
||||
title: "快速上手",
|
||||
},
|
||||
"deployment-guide": {
|
||||
title: "部署指南",
|
||||
},
|
||||
configuration: {
|
||||
title: "配置",
|
||||
},
|
||||
"workspace-usage": {
|
||||
title: "工作区使用",
|
||||
},
|
||||
"agents-and-threads": {
|
||||
title: "Agent 与线程",
|
||||
},
|
||||
"operations-and-troubleshooting": {
|
||||
title: "运维与排障",
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
@@ -0,0 +1,114 @@
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
|
||||
# Agent 与线程
|
||||
|
||||
<Callout type="info" emoji="🤖">
|
||||
Agent 是配置单元——它们定义了一组能力。线程是对话实例,带有持久化状态和历史记录。
|
||||
</Callout>
|
||||
|
||||
## 自定义 Agent
|
||||
|
||||
DeerFlow 允许你创建多个具有不同专业领域的自定义 Agent。每个 Agent 使用 DeerFlow Harness 相同的 Lead Agent 运行时,但具有不同的:
|
||||
|
||||
- 模型(例如为一个 Agent 使用 GPT-4o,为另一个使用 Claude)
|
||||
- 系统提示和指令
|
||||
- 技能(例如专注于数据分析的 Agent 只加载数据分析技能)
|
||||
- 工具访问(通过工具组)
|
||||
|
||||
### 创建自定义 Agent
|
||||
|
||||
<Steps>
|
||||
|
||||
#### 通过界面
|
||||
|
||||
1. 打开 DeerFlow 应用。
|
||||
2. 点击侧边栏中的 **Agents**(Agent 管理)。
|
||||
3. 点击 **New Agent**(新建 Agent)。
|
||||
4. 填写名称、描述和配置。
|
||||
5. 保存——Agent 立即可用,无需重启。
|
||||
|
||||
#### 通过 API
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8001/api/agents \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"display_name": "数据分析师",
|
||||
"description": "专业的数据分析和可视化",
|
||||
"skills": ["data-analysis", "chart-visualization"]
|
||||
}'
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
### Agent 名称和 Slug
|
||||
|
||||
创建 Agent 时,`display_name` 对用户显示,系统内部使用自动派生的 ASCII `slug`(`name` 字段)来标识 Agent。
|
||||
|
||||
- `display_name`:对用户显示的任意字符串(例如 "数据分析师")
|
||||
- `name`(slug):用于 API 和文件路径的 ASCII 标识符(例如 `data-analyst`)
|
||||
|
||||
如果派生的 slug 与现有 Agent 冲突,`/api/agents/check` 端点会建议一个唯一的替代名称。
|
||||
|
||||
### Agent 存储
|
||||
|
||||
自定义 Agent 配置存储在 `backend/agents/{name}/config.yaml` 中。你可以直接编辑这些文件——更改在下次 Agent 调用时自动加载。
|
||||
|
||||
## 线程生命周期
|
||||
|
||||
线程是对话及其所有相关状态的完整封装:消息历史、产出物、待办列表和检查点数据。
|
||||
|
||||
### 创建
|
||||
|
||||
线程在你发送第一条消息时创建。线程 ID 是自动生成的 UUID(由前端生成),用于标识所有后续请求中的对话。
|
||||
|
||||
### 执行
|
||||
|
||||
每次你发送消息,LangGraph 从最新检查点恢复线程状态,运行 Lead Agent,并更新状态。流式事件在 Agent 工作时发送到浏览器。
|
||||
|
||||
### 检查点和持久化
|
||||
|
||||
DeerFlow 在每次 Agent 轮次后自动保存线程状态(如果配置了检查点器)。这允许:
|
||||
|
||||
- 在服务器重启后恢复线程。
|
||||
- 在长时间间隔后继续对话。
|
||||
- 在出现问题时重放或从特定时间点恢复。
|
||||
|
||||
配置检查点器:
|
||||
|
||||
```yaml
|
||||
checkpointer:
|
||||
type: sqlite
|
||||
connection_string: .deer-flow/checkpoints.db
|
||||
```
|
||||
|
||||
对于生产高负载环境使用 Redis:
|
||||
|
||||
```yaml
|
||||
checkpointer:
|
||||
type: redis
|
||||
connection_string: redis://localhost:6379/0
|
||||
```
|
||||
|
||||
### 线程数据目录
|
||||
|
||||
每个线程在 `.deer-flow/threads/{thread_id}/` 下有一个专用目录:
|
||||
|
||||
```
|
||||
.deer-flow/threads/{thread_id}/
|
||||
user-data/
|
||||
uploads/ ← 用户上传的文件
|
||||
outputs/ ← Agent 生成的产出物
|
||||
workspace/ ← 会话工作文件
|
||||
```
|
||||
|
||||
删除线程会移除其检查点数据,但用户数据目录会单独管理(取决于删除配置)。
|
||||
|
||||
### 恢复线程
|
||||
|
||||
线程以其持久化状态自动恢复。从侧边栏选择任何过往线程即可从停止处继续——Agent 会记住所有消息和产出物。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="工作区使用" href="/docs/application/workspace-usage" />
|
||||
<Cards.Card title="运维与排障" href="/docs/application/operations-and-troubleshooting" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,215 @@
|
||||
import { Callout, Cards, Tabs } from "nextra/components";
|
||||
|
||||
# 配置
|
||||
|
||||
本页面涵盖 DeerFlow 应用的所有配置层——`config.yaml`、前端环境变量、`extensions_config.json` 和运行时环境变量。
|
||||
|
||||
## config.yaml
|
||||
|
||||
`config.yaml` 是 DeerFlow 的主要配置文件。所有 Agent 行为、模型选择、工具加载和运行时功能都由它控制。
|
||||
|
||||
参见[配置](/docs/harness/configuration)参考页面了解文件格式和每个章节的详细说明。
|
||||
|
||||
### 模型提供商
|
||||
|
||||
<Tabs items={["OpenAI", "Claude", "Gemini", "DeepSeek", "Ollama(本地)"]}>
|
||||
<Tabs.Tab>
|
||||
```yaml
|
||||
models:
|
||||
- name: gpt-4o
|
||||
use: langchain_openai:ChatOpenAI
|
||||
model: gpt-4o
|
||||
api_key: $OPENAI_API_KEY
|
||||
request_timeout: 600.0
|
||||
max_retries: 2
|
||||
supports_vision: true
|
||||
thinking_enabled: false
|
||||
```
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```yaml
|
||||
models:
|
||||
- name: claude-sonnet
|
||||
use: langchain_anthropic:ChatAnthropic
|
||||
model: claude-sonnet-4-5
|
||||
api_key: $ANTHROPIC_API_KEY
|
||||
max_tokens: 16000
|
||||
supports_vision: true
|
||||
thinking_enabled: false
|
||||
```
|
||||
|
||||
启用扩展思考:
|
||||
|
||||
```yaml
|
||||
- name: claude-extended-thinking
|
||||
use: langchain_anthropic:ChatAnthropic
|
||||
model: claude-sonnet-4-5
|
||||
api_key: $ANTHROPIC_API_KEY
|
||||
max_tokens: 16000
|
||||
thinking_enabled: true
|
||||
extra_body:
|
||||
thinking:
|
||||
type: enabled
|
||||
budget_tokens: 10000
|
||||
```
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```yaml
|
||||
models:
|
||||
- name: gemini
|
||||
use: langchain_google_genai:ChatGoogleGenerativeAI
|
||||
model: gemini-2.5-pro-preview-03-25
|
||||
api_key: $GEMINI_API_KEY
|
||||
request_timeout: 600.0
|
||||
max_retries: 2
|
||||
supports_vision: true
|
||||
thinking_enabled: false
|
||||
```
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```yaml
|
||||
models:
|
||||
- name: deepseek
|
||||
use: langchain_openai:ChatOpenAI
|
||||
model: deepseek-reasoner
|
||||
api_key: $DEEPSEEK_API_KEY
|
||||
base_url: https://api.deepseek.com
|
||||
request_timeout: 600.0
|
||||
max_retries: 2
|
||||
supports_vision: false
|
||||
thinking_enabled: true
|
||||
```
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```yaml
|
||||
models:
|
||||
- name: ollama-llama
|
||||
use: langchain_ollama:ChatOllama
|
||||
model: llama3.3
|
||||
base_url: http://localhost:11434
|
||||
request_timeout: 600.0
|
||||
max_retries: 2
|
||||
supports_vision: false
|
||||
thinking_enabled: false
|
||||
```
|
||||
|
||||
确保 Ollama 已运行并已拉取所需模型:
|
||||
|
||||
```bash
|
||||
ollama pull llama3.3
|
||||
```
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
|
||||
### 沙箱
|
||||
|
||||
```yaml
|
||||
# 本地开发(默认)
|
||||
sandbox:
|
||||
use: deerflow.sandbox.local:LocalSandboxProvider
|
||||
allow_host_bash: false
|
||||
|
||||
# 基于容器(推荐用于多用户)
|
||||
sandbox:
|
||||
use: deerflow.community.aio_sandbox:AioSandboxProvider
|
||||
replicas: 3
|
||||
idle_timeout: 600
|
||||
```
|
||||
|
||||
### 工具
|
||||
|
||||
参见[工具](/docs/harness/tools)页面了解完整的工具配置参考。快速参考:
|
||||
|
||||
```yaml
|
||||
tools:
|
||||
- use: deerflow.community.ddg_search.tools:web_search_tool
|
||||
- use: deerflow.community.jina_ai.tools:web_fetch_tool
|
||||
- use: deerflow.sandbox.tools:ls_tool
|
||||
- use: deerflow.sandbox.tools:read_file_tool
|
||||
- use: deerflow.sandbox.tools:write_file_tool
|
||||
- use: deerflow.sandbox.tools:bash_tool
|
||||
```
|
||||
|
||||
### 技能
|
||||
|
||||
```yaml
|
||||
skills:
|
||||
container_path: /mnt/skills
|
||||
# path: /custom/path/to/skills # 可选;默认为仓库 skills/ 目录
|
||||
```
|
||||
|
||||
技能可用性在 `extensions_config.json` 中管理(参见下方)。
|
||||
|
||||
### 检查点(线程持久化)
|
||||
|
||||
```yaml
|
||||
checkpointer:
|
||||
type: sqlite
|
||||
connection_string: .deer-flow/checkpoints.db
|
||||
|
||||
# 或使用 Redis(高负载生产环境):
|
||||
# checkpointer:
|
||||
# type: redis
|
||||
# connection_string: redis://localhost:6379/0
|
||||
```
|
||||
|
||||
## 前端环境变量
|
||||
|
||||
前端通过 `.env.local`(本地开发)或 Docker Compose 环境中的环境变量配置。
|
||||
|
||||
| 变量 | 必需 | 描述 |
|
||||
|---|---|---|
|
||||
| `BETTER_AUTH_SECRET` | 是(生产) | 会话管理的密钥(最少 32 个字符) |
|
||||
| `BETTER_AUTH_URL` | 推荐 | 你的应用公开 URL(例如 `https://your-domain.com`) |
|
||||
| `SKIP_ENV_VALIDATION` | 否 | 设为 `1` 跳过构建时环境变量验证 |
|
||||
|
||||
本地开发:
|
||||
|
||||
```bash
|
||||
# frontend/.env.local
|
||||
BETTER_AUTH_SECRET=local-dev-secret-at-least-32-chars
|
||||
```
|
||||
|
||||
<Callout type="warning">
|
||||
不要在生产中使用 <code>SKIP_ENV_VALIDATION=1</code>。为 <code>BETTER_AUTH_SECRET</code> 设置一个真实值。
|
||||
</Callout>
|
||||
|
||||
## extensions_config.json
|
||||
|
||||
`extensions_config.json` 控制 MCP 服务器和技能的运行时启用状态,独立于 `config.yaml`。
|
||||
|
||||
默认位置:项目根目录(与 `config.yaml` 同一目录)。
|
||||
|
||||
### MCP 服务器
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"filesystem": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"],
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 技能启用状态
|
||||
|
||||
技能启用状态会反映在 `extensions_config.json` 中。你可以直接编辑它,或通过 DeerFlow 应用界面进行管理。
|
||||
|
||||
## 运行时环境变量
|
||||
|
||||
这些变量在 DeerFlow 进程中设置(通过 `.env`、Docker 环境或 shell):
|
||||
|
||||
| 变量 | 默认值 | 描述 |
|
||||
|---|---|---|
|
||||
| `DEER_FLOW_CONFIG_PATH` | 自动发现 | `config.yaml` 的绝对路径 |
|
||||
| `LOG_LEVEL` | `info` | 日志详细程度(`debug`/`info`/`warning`/`error`) |
|
||||
| `DEER_FLOW_ROOT` | 仓库根目录 | 用于 Docker 中的技能和线程挂载 |
|
||||
| `LANGGRAPH_UPSTREAM` | `langgraph:2024` | nginx 代理的 LangGraph 地址 |
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="Harness 配置" href="/docs/harness/configuration" />
|
||||
<Cards.Card title="部署指南" href="/docs/application/deployment-guide" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,199 @@
|
||||
import { Callout, Cards, Steps, Tabs } from "nextra/components";
|
||||
|
||||
# 部署指南
|
||||
|
||||
本指南涵盖 DeerFlow 应用所有支持的部署方式:本地开发、Docker Compose 以及使用 Kubernetes 管理沙箱的生产环境。
|
||||
|
||||
## 本地开发部署
|
||||
|
||||
本地工作流是运行 DeerFlow 最快的方式,所有服务作为原生进程在你的机器上运行。
|
||||
|
||||
<Tabs items={["启动", "停止", "日志"]}>
|
||||
<Tabs.Tab>
|
||||
```bash
|
||||
make dev
|
||||
```
|
||||
|
||||
启动的服务:
|
||||
|
||||
| 服务 | 端口 | 描述 |
|
||||
|---|---|---|
|
||||
| LangGraph | 2024 | DeerFlow Harness 运行时 |
|
||||
| Gateway API | 8001 | FastAPI 后端 |
|
||||
| 前端 | 3000 | Next.js 界面 |
|
||||
| nginx | 2026 | 统一反向代理 |
|
||||
|
||||
访问地址:**http://localhost:2026**
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```bash
|
||||
make stop
|
||||
```
|
||||
|
||||
停止所有四个服务。即使某个服务没有运行也可以安全执行。
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```
|
||||
logs/langgraph.log # Agent 运行时日志
|
||||
logs/gateway.log # API Gateway 日志
|
||||
logs/frontend.log # Next.js 开发服务器日志
|
||||
logs/nginx.log # nginx 访问/错误日志
|
||||
```
|
||||
|
||||
实时追踪日志:
|
||||
```bash
|
||||
tail -f logs/langgraph.log
|
||||
```
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
|
||||
## Docker Compose 部署
|
||||
|
||||
Docker Compose 在容器中运行所有服务。适用于更接近生产的本地设置或团队环境。
|
||||
|
||||
### 前置条件
|
||||
|
||||
- Docker(macOS 上的 Docker Desktop 或 OrbStack)
|
||||
- 在仓库根目录中已配置的 `config.yaml`
|
||||
|
||||
### 开发 Compose
|
||||
|
||||
```bash
|
||||
# 设置 deer-flow 仓库根目录的绝对路径
|
||||
export DEER_FLOW_ROOT=/path/to/deer-flow
|
||||
|
||||
docker compose -f docker/docker-compose-dev.yaml up --build
|
||||
```
|
||||
|
||||
访问地址:**http://localhost:2026**
|
||||
|
||||
### 环境变量
|
||||
|
||||
在仓库根目录创建 `.env` 文件用于存放密钥和运行时配置:
|
||||
|
||||
```bash
|
||||
# .env
|
||||
OPENAI_API_KEY=sk-...
|
||||
DEER_FLOW_ROOT=/absolute/path/to/deer-flow
|
||||
BETTER_AUTH_SECRET=your-secret-here-min-32-chars
|
||||
```
|
||||
|
||||
`docker-compose*.yaml` 文件包含 `env_file: ../.env` 指令,会自动加载该文件。
|
||||
|
||||
<Callout type="warning">
|
||||
在部署前始终将 <code>BETTER_AUTH_SECRET</code> 设置为强随机字符串。没有它,前端构建会使用一个公开已知的默认值。
|
||||
</Callout>
|
||||
|
||||
### 数据持久化
|
||||
|
||||
线程数据存储在 `backend/.deer-flow/threads/`。在 Docker 部署中,此目录被绑定挂载到 langgraph 容器中。
|
||||
|
||||
为避免容器重建时数据丢失:
|
||||
|
||||
1. 将 `DEER_FLOW_ROOT` 设置为仓库根目录的绝对路径。
|
||||
2. 验证 `threads/` 和 `skills/` 目录挂载正确。
|
||||
|
||||
对于生产环境,使用命名卷或持久化卷声明(PVC)代替主机绑定挂载。
|
||||
|
||||
## 生产部署注意事项
|
||||
|
||||
### 沙箱模式选择
|
||||
|
||||
| 沙箱 | 使用场景 |
|
||||
|---|---|
|
||||
| `LocalSandboxProvider` | 单用户、受信任的本地工作流 |
|
||||
| `AioSandboxProvider`(Docker) | 多用户、中等隔离需求 |
|
||||
| `AioSandboxProvider` + K8s Provisioner | 生产环境、强隔离、多用户 |
|
||||
|
||||
对于有多个并发用户的任何部署,使用基于容器的沙箱,防止用户之间的执行环境相互干扰。
|
||||
|
||||
### K8s Provisioner 配置
|
||||
|
||||
<Steps>
|
||||
|
||||
#### 配置 Provisioner
|
||||
|
||||
在你的 `.env` 或 compose 覆盖文件中设置必需的环境变量:
|
||||
|
||||
```bash
|
||||
K8S_NAMESPACE=deer-flow
|
||||
SANDBOX_IMAGE=enterprise-public-cn-beijing.cr.volces.com/vefaas-public/all-in-one-sandbox:latest
|
||||
DEER_FLOW_ROOT=/absolute/path/to/deer-flow
|
||||
```
|
||||
|
||||
#### 配置沙箱提供者
|
||||
|
||||
```yaml
|
||||
# config.yaml
|
||||
sandbox:
|
||||
use: deerflow.community.aio_sandbox:AioSandboxProvider
|
||||
provisioner_url: http://provisioner:8002
|
||||
```
|
||||
|
||||
#### 配置数据持久化
|
||||
|
||||
对于生产环境,使用 PVC 代替 hostPath 卷:
|
||||
|
||||
```bash
|
||||
# 在 .env 或 compose 环境中
|
||||
USERDATA_PVC_NAME=deer-flow-userdata-pvc
|
||||
SKILLS_PVC_NAME=deer-flow-skills-pvc
|
||||
```
|
||||
|
||||
当设置 `USERDATA_PVC_NAME` 时,Provisioner 自动使用子路径(`threads/{thread_id}/user-data`),每个线程在 PVC 中获得自己的目录。
|
||||
|
||||
</Steps>
|
||||
|
||||
### nginx 配置
|
||||
|
||||
nginx 路由所有流量,控制路由的关键环境变量:
|
||||
|
||||
| 变量 | 默认值 | 描述 |
|
||||
|---|---|---|
|
||||
| `LANGGRAPH_UPSTREAM` | `langgraph:2024` | LangGraph 服务地址 |
|
||||
| `LANGGRAPH_REWRITE` | `/` | LangGraph 路由的 URL 重写前缀 |
|
||||
|
||||
这些在 Docker Compose 环境中设置,并在容器启动时由 `envsubst` 处理。
|
||||
|
||||
### 认证配置
|
||||
|
||||
DeerFlow 应用使用 [Better Auth](https://www.better-auth.com/) 进行会话管理。在生产环境中:
|
||||
|
||||
1. 将 `BETTER_AUTH_SECRET` 设置为强随机字符串(最少 32 个字符)。
|
||||
2. 将 `BETTER_AUTH_URL` 设置为你的公开 URL(例如 `https://your-domain.com`)。
|
||||
|
||||
```bash
|
||||
# 生成密钥
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
### 资源建议
|
||||
|
||||
| 服务 | 最低配置 | 推荐配置 |
|
||||
|---|---|---|
|
||||
| LangGraph(Agent 运行时) | 2 vCPU、4 GB RAM | 4 vCPU、8 GB RAM |
|
||||
| Gateway | 0.5 vCPU、512 MB | 1 vCPU、1 GB |
|
||||
| 前端 | 0.5 vCPU、512 MB | 1 vCPU、1 GB |
|
||||
| 沙箱容器(每会话) | 1 vCPU、1 GB | 2 vCPU、2 GB |
|
||||
|
||||
## 部署后验证
|
||||
|
||||
启动后验证部署:
|
||||
|
||||
```bash
|
||||
# 检查 Gateway 健康状态
|
||||
curl http://localhost:8001/health
|
||||
|
||||
# 检查 LangGraph 健康状态
|
||||
curl http://localhost:2024/ok
|
||||
|
||||
# 通过 nginx 列出配置的模型(验证完整代理链)
|
||||
curl http://localhost:2026/api/models
|
||||
```
|
||||
|
||||
正常工作的部署会从每个端点返回 `200` 响应。`/api/models` 调用会返回你 `config.yaml` 中的模型列表。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="配置" href="/docs/application/configuration" />
|
||||
<Cards.Card title="运维与排障" href="/docs/application/operations-and-troubleshooting" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,65 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# DeerFlow 应用
|
||||
|
||||
<Callout type="info" emoji="🚀">
|
||||
DeerFlow 应用是构建在 DeerFlow Harness 之上的完整 Super Agent 应用。它将运行时能力打包成一个可部署的产品,包含 Web 界面、API Gateway 和运维工具。
|
||||
</Callout>
|
||||
|
||||
DeerFlow 应用是 DeerFlow 生产体验的参考实现。它将 Harness 运行时、基于 Web 的对话工作区、API Gateway 和反向代理组合成一个可部署的完整系统。
|
||||
|
||||
## 应用提供什么
|
||||
|
||||
| 能力 | 描述 |
|
||||
|---|---|
|
||||
| **Web 工作区** | 浏览器对话界面,支持线程、产出物、文件上传和技能选择 |
|
||||
| **自定义 Agent** | 创建和管理具有不同模型、技能和工具集的命名 Agent |
|
||||
| **线程管理** | 带检查点和历史记录的持久化对话线程 |
|
||||
| **流式响应** | 实时 token 流式传输,带思考步骤和工具调用可见性 |
|
||||
| **产出物查看器** | Agent 生成文件和输出的浏览器内预览和下载 |
|
||||
| **扩展界面** | 无需编辑配置文件即可启用/禁用 MCP 服务器和技能 |
|
||||
| **Gateway API** | 桥接前端和 LangGraph 运行时的基于 FastAPI 的 REST API |
|
||||
|
||||
## 架构
|
||||
|
||||
DeerFlow 应用以四个服务的形式运行,通过单个 nginx 反向代理提供:
|
||||
|
||||
```
|
||||
┌──────────────────┐
|
||||
浏览器 → │ nginx :2026 │
|
||||
└──────────────────┘
|
||||
│ │
|
||||
┌────────┘ └────────┐
|
||||
▼ ▼
|
||||
┌──────────────────┐ ┌──────────────────────┐
|
||||
│ 前端 :3000 │ │ Gateway API :8001 │
|
||||
│ (Next.js) │ │ (FastAPI) │
|
||||
└──────────────────┘ └──────────────────────┘
|
||||
│
|
||||
┌─────────┘
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ LangGraph :2024 │
|
||||
│ (DeerFlow Harness) │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
- **nginx**:路由请求——`/api/*` 到 Gateway,LangGraph 流式端点到 LangGraph,其余到前端。
|
||||
- **前端**(Next.js + React):浏览器界面,与 Gateway 和 LangGraph 通信。
|
||||
- **Gateway**(FastAPI):处理 API 操作——模型列表、Agent CRUD、记忆、扩展管理、文件上传。
|
||||
- **LangGraph**:DeerFlow Harness 运行时,管理线程状态、Agent 执行和流式传输。
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 层次 | 技术 |
|
||||
|---|---|
|
||||
| 前端 | Next.js 16、React 19、TypeScript、pnpm |
|
||||
| Gateway | FastAPI、Python 3.12、uvicorn |
|
||||
| Agent 运行时 | LangGraph、LangChain、DeerFlow Harness |
|
||||
| 反向代理 | nginx |
|
||||
| 状态持久化 | LangGraph Server(默认)+ 可选 SQLite/PostgreSQL 检查点 |
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="快速上手" href="/docs/application/quick-start" />
|
||||
<Cards.Card title="部署指南" href="/docs/application/deployment-guide" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,165 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# 运维与排障
|
||||
|
||||
本页面涵盖运行 DeerFlow 应用的操作信息:日志记录、常见问题和维护任务。
|
||||
|
||||
## 日志
|
||||
|
||||
DeerFlow 应用在 `logs/` 目录中写入每个服务的日志:
|
||||
|
||||
| 文件 | 内容 |
|
||||
|---|---|
|
||||
| `logs/langgraph.log` | Agent 运行时、工具调用、LangGraph 错误 |
|
||||
| `logs/gateway.log` | API 请求/响应、Gateway 错误 |
|
||||
| `logs/frontend.log` | Next.js 服务器日志 |
|
||||
| `logs/nginx.log` | 代理访问和错误日志 |
|
||||
|
||||
**实时追踪日志**:
|
||||
|
||||
```bash
|
||||
tail -f logs/langgraph.log # 查看 Agent 活动
|
||||
tail -f logs/gateway.log # 查看 API 请求
|
||||
```
|
||||
|
||||
**调整日志级别**:
|
||||
|
||||
```yaml
|
||||
# config.yaml
|
||||
log_level: debug # debug | info | warning | error
|
||||
```
|
||||
|
||||
## 健康检查
|
||||
|
||||
DeerFlow 暴露健康检查端点:
|
||||
|
||||
```bash
|
||||
# Gateway 健康状态
|
||||
curl http://localhost:8001/health
|
||||
|
||||
# LangGraph 健康状态
|
||||
curl http://localhost:2024/ok
|
||||
|
||||
# 通过 nginx 完整代理链验证
|
||||
curl http://localhost:2026/api/models
|
||||
```
|
||||
|
||||
## 配置升级
|
||||
|
||||
当 `config.yaml` schema 更新时(由 `config_version` 字段标识),运行:
|
||||
|
||||
```bash
|
||||
make config-upgrade
|
||||
```
|
||||
|
||||
这将 `config.example.yaml` 中的新字段合并到你现有的 `config.yaml` 中,而不覆盖你的自定义内容。
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 模型配置错误
|
||||
|
||||
**症状**:Agent 在响应第一条消息时报错,日志中有 API 认证错误。
|
||||
|
||||
**诊断**:
|
||||
```bash
|
||||
# 检查 LangGraph 日志中的模型错误
|
||||
grep -i "error\|apikey\|unauthorized" logs/langgraph.log | tail -20
|
||||
```
|
||||
|
||||
**解决**:
|
||||
1. 验证 `config.yaml` 中 API key 字段名称正确(例如 `$OPENAI_API_KEY`)。
|
||||
2. 确认对应的环境变量已设置(`echo $OPENAI_API_KEY`)。
|
||||
3. 检查 `base_url`(如有)是否与提供商的实际端点匹配。
|
||||
|
||||
---
|
||||
|
||||
### 沙箱权限问题
|
||||
|
||||
**症状**:工具报"文件未找到"或权限错误,即使 Agent 声称已创建文件。
|
||||
|
||||
**诊断**:
|
||||
```bash
|
||||
# 检查线程用户数据目录是否存在且可写
|
||||
ls -la backend/.deer-flow/threads/
|
||||
```
|
||||
|
||||
**解决**:
|
||||
1. 确保 `backend/.deer-flow/` 对运行 DeerFlow 的进程可写。
|
||||
2. 在 Docker 部署中,验证卷挂载路径正确(`DEER_FLOW_ROOT` 设置为绝对路径)。
|
||||
3. 如果使用基于容器的沙箱,确认 Docker 已运行并且容器镜像已拉取。
|
||||
|
||||
---
|
||||
|
||||
### 前端构建失败
|
||||
|
||||
**症状**:`make install` 或前端构建步骤失败,提示 `BETTER_AUTH_SECRET` 错误。
|
||||
|
||||
**解决**:
|
||||
```bash
|
||||
# 选项 1:设置环境变量(推荐)
|
||||
export BETTER_AUTH_SECRET=your-secret-here-at-least-32-chars
|
||||
cd frontend && pnpm build
|
||||
|
||||
# 选项 2:跳过构建时验证(仅限开发)
|
||||
SKIP_ENV_VALIDATION=1 pnpm build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### MCP 服务器连接失败
|
||||
|
||||
**症状**:MCP 工具未出现,`logs/langgraph.log` 中有超时错误。
|
||||
|
||||
**诊断**:
|
||||
```bash
|
||||
# 检查 MCP 相关错误
|
||||
grep -i "mcp\|timeout" logs/langgraph.log | tail -20
|
||||
```
|
||||
|
||||
**解决**:
|
||||
1. 验证 `extensions_config.json` 中 MCP 服务器的 `command` 和 `args` 在服务器外部正常工作(手动运行命令)。
|
||||
2. 确认 MCP 服务器的依赖(如 `npx`、`uvx`)已安装并在 PATH 中。
|
||||
3. 检查 MCP 服务器是否需要网络访问或特定环境变量。
|
||||
|
||||
---
|
||||
|
||||
### K8s Provisioner 连接失败
|
||||
|
||||
**症状**:沙箱工具请求挂起,日志中有连接拒绝错误。
|
||||
|
||||
**解决**:
|
||||
1. 验证 `config.yaml` 中 `provisioner_url` 正确且 Provisioner Pod 运行正常。
|
||||
2. 检查 `K8S_NAMESPACE` 和 RBAC 配置是否允许 Provisioner 创建 Pod。
|
||||
3. 验证 `SANDBOX_IMAGE` 可以从 K8s 节点拉取。
|
||||
|
||||
## 数据备份
|
||||
|
||||
DeerFlow 将持久化数据存储在:
|
||||
- **线程数据**:`backend/.deer-flow/threads/` — 每个线程的上传文件、输出和工作区文件
|
||||
- **检查点**:取决于检查点器配置(SQLite:`backend/.deer-flow/checkpoints.db`,Redis:外部存储)
|
||||
- **记忆**:`backend/.deer-flow/memory.json`(以及 `agents/*/memory.json`)
|
||||
- **自定义 Agent 配置**:`backend/agents/*/config.yaml`
|
||||
|
||||
对于生产部署,定期备份这些目录。Docker 部署中,确保这些目录绑定挂载到持久卷,而不是容器内部。
|
||||
|
||||
## 停止和重启服务
|
||||
|
||||
```bash
|
||||
# 停止所有本地服务
|
||||
make stop
|
||||
|
||||
# 重启(停止后重新启动)
|
||||
make stop && make dev
|
||||
```
|
||||
|
||||
在 Docker 中:
|
||||
|
||||
```bash
|
||||
docker compose -f docker/docker-compose-dev.yaml down
|
||||
docker compose -f docker/docker-compose-dev.yaml up
|
||||
```
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="部署指南" href="/docs/application/deployment-guide" />
|
||||
<Cards.Card title="配置" href="/docs/application/configuration" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,121 @@
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
|
||||
# 快速上手
|
||||
|
||||
<Callout type="info" emoji="⚡">
|
||||
大约 10 分钟即可在本地运行 DeerFlow 应用。你需要一台安装了 Python 3.12+、Node.js 22+ 的机器,以及至少一个 LLM API Key。
|
||||
</Callout>
|
||||
|
||||
本指南引导你使用 `make dev` 工作流在本地机器上启动 DeerFlow 应用。所有四个服务(LangGraph、Gateway、前端、nginx)一起启动,通过单个 URL 访问。
|
||||
|
||||
## 前置条件
|
||||
|
||||
检查所有必需工具是否已安装:
|
||||
|
||||
```bash
|
||||
make check
|
||||
```
|
||||
|
||||
必需工具:
|
||||
|
||||
| 工具 | 最低版本 |
|
||||
|---|---|
|
||||
| Python | 3.12 |
|
||||
| uv | 最新版 |
|
||||
| Node.js | 22 |
|
||||
| pnpm | 10 |
|
||||
| nginx | 任何近期版本 |
|
||||
|
||||
在 macOS 上,使用 `brew install python uv node pnpm nginx` 安装。在 Linux 上,使用你的发行版包管理器。
|
||||
|
||||
## 步骤
|
||||
|
||||
<Steps>
|
||||
|
||||
### 克隆仓库
|
||||
|
||||
```bash
|
||||
git clone https://github.com/bytedance/deer-flow.git
|
||||
cd deer-flow
|
||||
```
|
||||
|
||||
### 安装依赖
|
||||
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
|
||||
这会安装后端 Python 依赖(通过 `uv`)和前端 Node.js 依赖(通过 `pnpm`)。
|
||||
|
||||
### 创建配置文件
|
||||
|
||||
```bash
|
||||
cp config.example.yaml config.yaml
|
||||
```
|
||||
|
||||
然后编辑 `config.yaml` 至少添加一个模型:
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: gpt-4o
|
||||
use: langchain_openai:ChatOpenAI
|
||||
model: gpt-4o
|
||||
api_key: $OPENAI_API_KEY
|
||||
request_timeout: 600.0
|
||||
max_retries: 2
|
||||
supports_vision: true
|
||||
```
|
||||
|
||||
启动前设置对应的环境变量:
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY=sk-...
|
||||
```
|
||||
|
||||
查看[配置](/docs/application/configuration)页面了解其他模型提供商的示例。
|
||||
|
||||
### 启动所有服务
|
||||
|
||||
```bash
|
||||
make dev
|
||||
```
|
||||
|
||||
这会启动:
|
||||
- LangGraph 服务,端口 `2024`
|
||||
- Gateway API,端口 `8001`
|
||||
- 前端,端口 `3000`
|
||||
- nginx 反向代理,端口 `2026`
|
||||
|
||||
在浏览器中打开 [http://localhost:2026](http://localhost:2026)。
|
||||
|
||||
### 停止所有服务
|
||||
|
||||
```bash
|
||||
make stop
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
## `make dev` 做了什么
|
||||
|
||||
- 首先停止已有的服务进程(在启动被中断后安全运行)。
|
||||
- 每个服务在后台启动,日志写入 `logs/` 目录。
|
||||
- nginx 通过端口 `2026` 代理所有流量,所以你只需要一个 URL。
|
||||
|
||||
日志文件:
|
||||
|
||||
| 服务 | 日志文件 |
|
||||
|---|---|
|
||||
| LangGraph | `logs/langgraph.log` |
|
||||
| Gateway | `logs/gateway.log` |
|
||||
| 前端 | `logs/frontend.log` |
|
||||
| nginx | `logs/nginx.log` |
|
||||
|
||||
<Callout type="tip">
|
||||
如果有问题,先检查日志文件。大多数启动错误(缺失 API Key、配置解析失败)会出现在 <code>logs/langgraph.log</code> 或 <code>logs/gateway.log</code> 中。
|
||||
</Callout>
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="部署指南" href="/docs/application/deployment-guide" />
|
||||
<Cards.Card title="配置" href="/docs/application/configuration" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,87 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# 工作区使用
|
||||
|
||||
<Callout type="info" emoji="💬">
|
||||
DeerFlow 工作区是你与 Agent 交互的地方。本页面涵盖主要用户界面工作流——创建对话、上传文件、查看产出物和使用技能。
|
||||
</Callout>
|
||||
|
||||
DeerFlow 工作区是一个基于浏览器的对话界面,你可以在其中向 Agent 发送消息、上传文件、查看中间步骤,以及下载生成的产出物。
|
||||
|
||||
## 新建对话
|
||||
|
||||
1. 打开 [http://localhost:2026](http://localhost:2026)。
|
||||
2. 在主界面点击 **New Thread**(新建线程)按钮,或直接在输入框中输入消息。
|
||||
3. 输入你的第一条消息并发送。
|
||||
|
||||
每个对话是一个**线程**,有独立的历史记录、产出物和检查点。
|
||||
|
||||
## 选择模型
|
||||
|
||||
在消息输入区域,点击**模型选择器**从 `config.yaml` 中配置的模型中选择。默认选中第一个配置的模型。
|
||||
|
||||
你可以在对话中途切换模型——每次新的发送都会使用所选的模型。
|
||||
|
||||
## 选择 Agent
|
||||
|
||||
打开 **Agent 选择器**从可用 Agent 中选择:
|
||||
|
||||
- **默认 Agent**:使用所有全局工具和技能的通用 Agent。
|
||||
- **自定义 Agent**:具有专门技能组合、工具访问和提示词的命名 Agent。
|
||||
|
||||
参见 [Agent 与线程](/docs/application/agents-and-threads)页面了解如何创建自定义 Agent。
|
||||
|
||||
## 上传文件
|
||||
|
||||
拖放文件到消息输入区域,或点击附件图标上传。上传的文件挂载在沙箱的 `/mnt/user-data/uploads/` 路径下,Agent 可以直接读取和处理。
|
||||
|
||||
**支持的操作**:
|
||||
- 读取和分析文件内容
|
||||
- 处理数据文件(CSV、JSON、Excel)
|
||||
- 提取 PDF 内容
|
||||
- 分析图像(需要支持视觉的模型)
|
||||
|
||||
<Callout type="tip">
|
||||
上传大文件时,告诉 Agent 文件的具体内容,以便获得更好的结果(例如"分析这个包含季度销售数据的 CSV")。
|
||||
</Callout>
|
||||
|
||||
## 使用技能
|
||||
|
||||
某些 Agent 配置暴露了**技能选择器**。技能告诉 Agent 要执行哪类工作(深度研究、数据分析、图表生成等)。
|
||||
|
||||
在输入框中点击技能选择器选择一个技能。选定的技能会将专业指令和工作流注入到当前对话中。
|
||||
|
||||
## 查看 Agent 思考过程
|
||||
|
||||
当 Agent 调用工具或进行推理时,你可以展开**思考步骤**:
|
||||
|
||||
- **工具调用**:Agent 正在调用哪个工具、使用什么参数。
|
||||
- **工具结果**:工具返回了什么。
|
||||
- **思考内容**(如果模型支持):模型的内部推理过程。
|
||||
- **待办列表**(计划模式):当前任务列表及其完成状态。
|
||||
|
||||
点击消息旁边的展开箭头查看完整的推理链。
|
||||
|
||||
## 查看产出物
|
||||
|
||||
当 Agent 生成文件(报告、图表、代码文件、演示文稿)时,它们会以**产出物**的形式出现在对话中。
|
||||
|
||||
点击产出物卡片:
|
||||
- 在浏览器中预览文件。
|
||||
- 下载文件到本地机器。
|
||||
- 复制文件内容。
|
||||
|
||||
产出物会持久保存在线程的用户数据目录中(`.deer-flow/threads/{thread_id}/user-data/outputs/`)。
|
||||
|
||||
## 管理线程
|
||||
|
||||
**查看过往线程**:使用侧边栏浏览之前的对话。
|
||||
|
||||
**重命名线程**:`TitleMiddleware` 会在第一次交互后自动生成标题。你也可以手动重命名线程。
|
||||
|
||||
**删除线程**:从线程侧边栏菜单中选择删除。这会移除线程状态和所有相关的用户数据文件。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="Agent 与线程" href="/docs/application/agents-and-threads" />
|
||||
<Cards.Card title="运维与排障" href="/docs/application/operations-and-troubleshooting" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { MetaRecord } from "nextra";
|
||||
|
||||
const meta: MetaRecord = {
|
||||
index: {
|
||||
title: "安装",
|
||||
},
|
||||
"quick-start": {
|
||||
title: "快速上手",
|
||||
},
|
||||
"design-principles": {
|
||||
title: "设计理念",
|
||||
},
|
||||
"lead-agent": {
|
||||
title: "Lead Agent",
|
||||
},
|
||||
middlewares: {
|
||||
title: "中间件",
|
||||
},
|
||||
configuration: {
|
||||
title: "配置",
|
||||
},
|
||||
memory: {
|
||||
title: "记忆系统",
|
||||
},
|
||||
tools: {
|
||||
title: "工具",
|
||||
},
|
||||
skills: {
|
||||
title: "技能",
|
||||
},
|
||||
sandbox: {
|
||||
title: "沙箱",
|
||||
},
|
||||
subagents: {
|
||||
title: "子 Agent",
|
||||
},
|
||||
mcp: {
|
||||
title: "MCP 集成",
|
||||
},
|
||||
customization: {
|
||||
title: "自定义与扩展",
|
||||
},
|
||||
"integration-guide": {
|
||||
title: "集成指南",
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
@@ -0,0 +1,154 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# 配置
|
||||
|
||||
<Callout type="info" emoji="⚙️">
|
||||
所有 DeerFlow Harness 行为都由 <code>config.yaml</code> 驱动。一个文件控制哪些模型可用、沙箱如何运行、加载哪些工具,以及每个子系统的行为。
|
||||
</Callout>
|
||||
|
||||
DeerFlow 的配置系统围绕一个目标设计:每一个有意义的行为都应该可以在配置文件中表达,而不是硬编码在应用程序中。这使部署可重现、可审计,并且易于按环境定制。
|
||||
|
||||
## 配置文件位置
|
||||
|
||||
DeerFlow 使用以下优先级顺序解析 `config.yaml`:
|
||||
|
||||
1. 显式传递给 `AppConfig.from_file(config_path)` 的路径。
|
||||
2. `DEER_FLOW_CONFIG_PATH` 环境变量。
|
||||
3. `backend/config.yaml`(相对于后端目录)。
|
||||
4. 仓库根目录中的 `config.yaml`。
|
||||
|
||||
如果这些路径都不存在,应用程序在启动时会报错。
|
||||
|
||||
要使用自定义位置:
|
||||
|
||||
```bash
|
||||
export DEER_FLOW_CONFIG_PATH=/path/to/my-config.yaml
|
||||
```
|
||||
|
||||
## 环境变量插值
|
||||
|
||||
任何字段值都可以使用 `$VAR_NAME` 语法引用环境变量:
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: gpt-4o
|
||||
api_key: $OPENAI_API_KEY
|
||||
```
|
||||
|
||||
这使密钥不出现在配置文件本身中,变量在运行时从进程环境解析。
|
||||
|
||||
## `use` 字段
|
||||
|
||||
许多配置条目使用 `use:` 字段来指定要实例化的 Python 类或对象,格式为:
|
||||
|
||||
```
|
||||
package.subpackage.module:ClassName
|
||||
```
|
||||
|
||||
或对于模块级对象:
|
||||
|
||||
```
|
||||
package.subpackage.module:variable_name
|
||||
```
|
||||
|
||||
示例:
|
||||
|
||||
```yaml
|
||||
sandbox:
|
||||
use: deerflow.sandbox.local:LocalSandboxProvider
|
||||
|
||||
tools:
|
||||
- use: deerflow.community.tavily.tools:web_search_tool
|
||||
api_key: $TAVILY_API_KEY
|
||||
```
|
||||
|
||||
这是 DeerFlow 实现可插拔性而不硬编码类引用的方式。
|
||||
|
||||
## 额外字段透传
|
||||
|
||||
对于模型配置,`ModelConfig` 使用 `pydantic ConfigDict(extra="allow")`。这意味着你在模型条目下添加的任何额外字段都直接传递给模型构造函数。这允许提供商特定选项(如 `extra_body`、`reasoning` 或自定义超时键)无需修改 Harness 即可工作:
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: my-model
|
||||
use: langchain_openai:ChatOpenAI
|
||||
model: gpt-4o
|
||||
api_key: $OPENAI_API_KEY
|
||||
some_provider_specific_option: value # 传递给 ChatOpenAI 构造函数
|
||||
```
|
||||
|
||||
## 配置版本
|
||||
|
||||
`config.yaml` 包含追踪 schema 版本的 `config_version` 字段:
|
||||
|
||||
```yaml
|
||||
config_version: 6
|
||||
```
|
||||
|
||||
当 schema 更改(新字段、重命名章节)时,此数字增加。如果你本地的 `config.yaml` 落后于当前版本,运行:
|
||||
|
||||
```bash
|
||||
make config-upgrade
|
||||
```
|
||||
|
||||
这将 `config.example.yaml` 中的新字段合并到你现有的 `config.yaml` 中,而不覆盖你的自定义内容。
|
||||
|
||||
## 模块配置速查表
|
||||
|
||||
下表将 `config.yaml` 中的每个顶层章节映射到其文档页面:
|
||||
|
||||
| 章节 | 描述 | 文档 |
|
||||
|---|---|---|
|
||||
| `log_level` | 日志级别(`debug`/`info`/`warning`/`error`) | — |
|
||||
| `models` | 可用的 LLM 模型 | [Lead Agent](/docs/harness/lead-agent) |
|
||||
| `token_usage` | 每次模型调用的 token 追踪 | [中间件](/docs/harness/middlewares) |
|
||||
| `tools` | 可用的 Agent 工具 | [工具](/docs/harness/tools) |
|
||||
| `tool_groups` | 工具的命名分组 | [工具](/docs/harness/tools) |
|
||||
| `tool_search` | 延迟/按需工具加载 | [工具](/docs/harness/tools) |
|
||||
| `sandbox` | 沙箱提供者和选项 | [沙箱](/docs/harness/sandbox) |
|
||||
| `skills` | 技能目录和容器路径 | [技能](/docs/harness/skills) |
|
||||
| `skill_evolution` | Agent 管理的技能创建 | [技能](/docs/harness/skills) |
|
||||
| `subagents` | 子 Agent 超时和最大轮次 | [子 Agent](/docs/harness/subagents) |
|
||||
| `acp_agents` | 外部 ACP Agent 集成 | [子 Agent](/docs/harness/subagents) |
|
||||
| `memory` | 跨会话记忆存储 | [记忆系统](/docs/harness/memory) |
|
||||
| `summarization` | 对话摘要压缩 | [中间件](/docs/harness/middlewares) |
|
||||
| `title` | 自动生成线程标题 | [中间件](/docs/harness/middlewares) |
|
||||
| `checkpointer` | 线程状态持久化 | [Agent 与线程](/docs/application/agents-and-threads) |
|
||||
| `guardrails` | 工具调用授权 | — |
|
||||
| `uploads` | 文件上传设置(PDF 转换器) | — |
|
||||
| `channels` | IM 频道集成(飞书、Slack 等) | — |
|
||||
|
||||
## 最小配置示例
|
||||
|
||||
最小有效的 `config.yaml` 至少需要一个模型和一个沙箱:
|
||||
|
||||
```yaml
|
||||
config_version: 6
|
||||
|
||||
models:
|
||||
- name: gpt-4o
|
||||
use: langchain_openai:ChatOpenAI
|
||||
model: gpt-4o
|
||||
api_key: $OPENAI_API_KEY
|
||||
request_timeout: 600.0
|
||||
max_retries: 2
|
||||
supports_vision: true
|
||||
|
||||
sandbox:
|
||||
use: deerflow.sandbox.local:LocalSandboxProvider
|
||||
|
||||
tools:
|
||||
- use: deerflow.community.ddg_search.tools:web_search_tool
|
||||
- use: deerflow.community.jina_ai.tools:web_fetch_tool
|
||||
- use: deerflow.sandbox.tools:ls_tool
|
||||
- use: deerflow.sandbox.tools:read_file_tool
|
||||
- use: deerflow.sandbox.tools:write_file_tool
|
||||
- use: deerflow.sandbox.tools:bash_tool
|
||||
```
|
||||
|
||||
从仓库根目录的 `config.example.yaml` 开始,取消注释你需要的章节。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="部署指南" href="/docs/application/deployment-guide" />
|
||||
<Cards.Card title="应用配置" href="/docs/application/configuration" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,150 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# 自定义与扩展
|
||||
|
||||
<Callout type="info" emoji="🔧">
|
||||
DeerFlow 设计为可适配的。你可以通过编写自定义中间件、添加新工具、构建技能包以及通过 config.yaml 的 <code>use:</code> 字段替换任何内置组件来扩展 Agent 行为。
|
||||
</Callout>
|
||||
|
||||
DeerFlow 的可插拔架构意味着系统的大多数部分都可以在不 fork 核心的情况下被替换或扩展。本页面列举了扩展点,并解释如何使用每一个。
|
||||
|
||||
## 自定义中间件
|
||||
|
||||
中间件是为 Lead Agent 添加行为的主要扩展点。它们包裹每次 LLM 调用,可以在模型调用前后读取和修改 Agent 的状态。
|
||||
|
||||
添加自定义中间件:
|
||||
|
||||
1. 实现 `langchain.agents.middleware` 中的 `AgentMiddleware` 接口。
|
||||
2. 在构建 Agent 时通过 `custom_middlewares` 参数传入你的中间件。
|
||||
|
||||
```python
|
||||
from langchain.agents.middleware import AgentMiddleware
|
||||
from deerflow.agents.thread_state import ThreadState
|
||||
|
||||
class AuditMiddleware(AgentMiddleware):
|
||||
async def on_start(self, state: ThreadState, config):
|
||||
# 在每次模型调用前运行
|
||||
print(f"[审计] 轮次开始:上下文中有 {len(state.messages)} 条消息")
|
||||
return state, config
|
||||
|
||||
async def on_end(self, state: ThreadState, config):
|
||||
# 在每次模型调用后运行
|
||||
print(f"[审计] 轮次结束:最后一条消息类型 = {state.messages[-1].type}")
|
||||
return state, config
|
||||
```
|
||||
|
||||
自定义中间件在链末尾 `ClarificationMiddleware` 之前注入,后者始终最后运行。
|
||||
|
||||
## 自定义工具
|
||||
|
||||
在 `config.yaml` 的 `tools:` 下注册新工具,将其添加到 Agent:
|
||||
|
||||
```yaml
|
||||
tools:
|
||||
- use: mypackage.tools:my_custom_tool
|
||||
api_key: $MY_TOOL_API_KEY
|
||||
```
|
||||
|
||||
你的工具必须是 LangChain `BaseTool` 或用 `@tool` 装饰的函数。它将使用 `use:` 类路径和配置条目中的任何额外字段实例化。
|
||||
|
||||
```python
|
||||
# mypackage/tools.py
|
||||
from langchain_core.tools import tool
|
||||
|
||||
@tool
|
||||
def my_custom_tool(query: str) -> str:
|
||||
"""搜索我的自定义数据源。"""
|
||||
return do_search(query)
|
||||
```
|
||||
|
||||
## 自定义沙箱提供者
|
||||
|
||||
沙箱可以通过实现 `SandboxProvider` 接口来替换:
|
||||
|
||||
```python
|
||||
from deerflow.sandbox.sandbox_provider import SandboxProvider
|
||||
|
||||
class MyCustomSandboxProvider(SandboxProvider):
|
||||
def acquire(self, thread_id: str | None = None) -> str:
|
||||
# 返回 sandbox_id
|
||||
...
|
||||
|
||||
def get(self, sandbox_id: str):
|
||||
# 返回此 id 的沙箱实例
|
||||
...
|
||||
|
||||
def release(self, sandbox_id: str) -> None:
|
||||
# 清理
|
||||
...
|
||||
```
|
||||
|
||||
然后在 `config.yaml` 中引用:
|
||||
|
||||
```yaml
|
||||
sandbox:
|
||||
use: mypackage.sandbox:MyCustomSandboxProvider
|
||||
```
|
||||
|
||||
## 自定义记忆存储
|
||||
|
||||
通过实现 `MemoryStorage` 将基于文件的记忆替换为任何持久化存储:
|
||||
|
||||
```python
|
||||
from deerflow.agents.memory.storage import MemoryStorage
|
||||
from typing import Any
|
||||
|
||||
class RedisMemoryStorage(MemoryStorage):
|
||||
def load(self, agent_name: str | None = None) -> dict[str, Any]:
|
||||
...
|
||||
|
||||
def reload(self, agent_name: str | None = None) -> dict[str, Any]:
|
||||
...
|
||||
|
||||
def save(self, memory_data: dict[str, Any], agent_name: str | None = None) -> bool:
|
||||
...
|
||||
```
|
||||
|
||||
在 `config.yaml` 中配置:
|
||||
|
||||
```yaml
|
||||
memory:
|
||||
storage_class: mypackage.storage:RedisMemoryStorage
|
||||
```
|
||||
|
||||
## 自定义技能
|
||||
|
||||
技能是最简单的扩展点。在 `skills/custom/your-skill-name/` 下创建一个目录,并在其中添加 `SKILL.md` 文件。技能将在下次 `load_skills()` 调用时自动被发现。
|
||||
|
||||
参见[技能](/docs/harness/skills)页面了解完整的目录结构和 `SKILL.md` 格式。
|
||||
|
||||
## 自定义模型
|
||||
|
||||
任何与 LangChain 兼容的聊天模型都可以通过在 `use:` 字段中指定来使用:
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: my-custom-model
|
||||
use: mypackage.models:MyCustomChatModel
|
||||
# 任何额外字段都作为 kwargs 传递给构造函数
|
||||
base_url: http://my-model-server:8080
|
||||
api_key: $MY_MODEL_API_KEY
|
||||
```
|
||||
|
||||
模型类必须实现 LangChain 的 `BaseChatModel` 接口。
|
||||
|
||||
## 自定义检查点
|
||||
|
||||
线程状态持久化可以使用任何与 LangGraph 兼容的检查点器:
|
||||
|
||||
```yaml
|
||||
checkpointer:
|
||||
type: sqlite
|
||||
connection_string: ./my-checkpoints.db
|
||||
```
|
||||
|
||||
对于自定义后端,实现 LangGraph 的 `BaseCheckpointSaver` 接口,并在初始化 `DeerFlowClient` 时以编程方式配置它。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="集成指南" href="/docs/harness/integration-guide" />
|
||||
<Cards.Card title="配置" href="/docs/harness/configuration" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,112 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# 设计理念
|
||||
|
||||
<Callout type="info" emoji="🏗️">
|
||||
DeerFlow 围绕一个核心思想构建:Agent 行为应该由小型、可观察、可替换的组件组合而成——而不是硬编码到固定的工作流图中。
|
||||
</Callout>
|
||||
|
||||
了解 DeerFlow Harness 背后的设计理念,有助于你有效地使用它、自信地扩展它,并推断 Agent 在生产环境中的行为方式。
|
||||
|
||||
## 为什么是 Harness,而非 Framework
|
||||
|
||||
框架提供抽象和构建块,你负责组装各部分并编写连接它们的胶水代码。
|
||||
|
||||
**Harness** 更进一步。它打包了一个有主张的、可直接运行的运行时,让 Agent 无需你每次重建相同的基础设施就能完成真实工作。
|
||||
|
||||
DeerFlow 之所以是 Harness,是因为它内置了:
|
||||
|
||||
- 带有工具路由的 Lead Agent
|
||||
- 包裹每次 LLM 调用的中间件链
|
||||
- 用于文件和命令的沙箱执行
|
||||
- 按需加载专业能力的技能
|
||||
- 用于委派并行工作的子 Agent
|
||||
- 跨会话连续性的记忆
|
||||
- 控制这一切的配置系统
|
||||
|
||||
你不需要从头设计编排层——Harness 就是编排层。
|
||||
|
||||
## 长时序任务是主要使用场景
|
||||
|
||||
DeerFlow 专为需要不止一次提示-响应交互的任务而设计。一个有用的长时序 Agent 必须:
|
||||
|
||||
1. 制定计划
|
||||
2. 按顺序调用工具
|
||||
3. 检查和修改文件
|
||||
4. 在失败时恢复
|
||||
5. 当任务太宽泛时委派给子 Agent
|
||||
6. 最终返回具体的产出物
|
||||
|
||||
DeerFlow 中的每一个架构决策都以这个使用场景为标准进行评估。短暂、无状态的交互很简单。在真实世界压力下的长时序、多步骤工作流才是目标。
|
||||
|
||||
## 中间件链优于继承
|
||||
|
||||
DeerFlow 不要求你子类化 Agent 或覆盖方法来改变其行为。相反,它使用一个**中间件链**来包裹每次 LLM 调用。
|
||||
|
||||
每个中间件都是一个小型、专注的插件,可以在模型调用前后检查或修改 Agent 的状态。Lead Agent 的行为完全由活跃的中间件决定。
|
||||
|
||||
这种设计有几个优点:
|
||||
|
||||
- 各个行为(记忆、摘要、澄清、循环检测)相互隔离,可独立测试。
|
||||
- 可以扩展链而无需触碰 Agent 的核心逻辑。
|
||||
- 每个中间件的效果是可见且可审计的,因为它只触及其声明的状态。
|
||||
|
||||
详见[中间件](/docs/harness/middlewares)页面的完整列表和配置说明。
|
||||
|
||||
## 技能提供专业化但不污染上下文
|
||||
|
||||
**技能**是面向任务的能力包,包含指令、工作流、最佳实践以及让 Agent 在特定工作类型中有效的工具或资源。
|
||||
|
||||
关键设计决策是技能**按需加载**。基础 Agent 保持通用。当任务需要深度研究时,加载研究技能;当任务需要数据分析时,加载分析技能。
|
||||
|
||||
这很重要,因为它保持了基础 Agent 上下文的清晰。为撰写学术论文而设计的专业提示词不会污染专注于编码的会话。技能在相关时注入内容,仅此而已。
|
||||
|
||||
## 沙箱是执行环境
|
||||
|
||||
DeerFlow 为 Agent 提供一个**沙箱**:一个隔离的工作区,Agent 可以在其中读取文件、写入输出、运行命令并生成产出物。
|
||||
|
||||
这将 Agent 从文本生成器转变为能够真正完成工作的系统。Agent 不只是描述要写什么代码,而是可以写代码、运行代码并验证结果。
|
||||
|
||||
隔离性很重要,因为执行应该可重现且可控。沙箱是 DeerFlow 支持真实行动而不仅仅是对话的原因。
|
||||
|
||||
## 上下文工程让长时序任务可控
|
||||
|
||||
上下文压力是长时序 Agent 的主要挑战。如果所有内容无限期累积在上下文窗口中,Agent 会变得越来越慢、越来越嘈杂、越来越不可靠。
|
||||
|
||||
DeerFlow 通过**上下文工程**来解决这个问题——有意识地控制 Agent 在每个步骤中看到、记住和忽略什么:
|
||||
|
||||
- **摘要压缩**:当对话变得太长时,旧轮次被摘要替代。Agent 保留含义而不是全量内容。
|
||||
- **子 Agent 上下文隔离**:当工作委派给子 Agent 时,子 Agent 只接收完成其任务所需的信息,而不是完整的父历史。
|
||||
- **外部工作记忆**:任务产生的文件和产出物保存在磁盘上,而不在上下文窗口中。Agent 在需要时引用它们。
|
||||
- **记忆注入**:跨会话事实以受控的 token 预算注入到系统提示中。
|
||||
|
||||
这是 DeerFlow 中最重要的思想之一。好的 Agent 行为不仅仅是关于更强大的模型,也关于在正确时间给模型提供正确的工作集。
|
||||
|
||||
## 配置驱动行为
|
||||
|
||||
DeerFlow 中所有有意义的行为都通过 `config.yaml` 控制。系统的设计使运维人员无需触碰代码就能改变 Agent 的行为——使用哪些模型、是否启用摘要压缩、如何限制子 Agent、哪些工具可用。
|
||||
|
||||
这个设计原则有三个含义:
|
||||
|
||||
1. **可重现性**:一个配置文件在某时间点完整描述了 Agent 的行为。
|
||||
2. **可部署性**:相同的代码在不同环境中运行方式不同,因为配置不同。
|
||||
3. **可审计性**:Agent 能做什么和不能做什么在一处可见。
|
||||
|
||||
环境变量插值(`api_key: $OPENAI_API_KEY`)将密钥排除在提交的配置文件之外,同时保持相同的结构。
|
||||
|
||||
## 总结
|
||||
|
||||
| 设计原则 | 实践含义 |
|
||||
|---|---|
|
||||
| Harness 而非 Framework | 开箱即用的运行时,所有基础设施已预先连接 |
|
||||
| 长时序优先 | 架构假设多步骤、多工具、多轮次任务 |
|
||||
| 中间件优于继承 | 行为由小型、隔离的插件组合而成 |
|
||||
| 技能提供专业化 | 领域能力按需注入,保持基础干净 |
|
||||
| 沙箱用于执行 | 真实文件和命令操作的隔离工作区 |
|
||||
| 上下文工程 | 主动管理 Agent 所见内容以保持有效性 |
|
||||
| 配置驱动 | 所有关键行为通过 `config.yaml` 控制 |
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="Lead Agent" href="/docs/harness/lead-agent" />
|
||||
<Cards.Card title="中间件" href="/docs/harness/middlewares" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# 安装 DeerFlow Harness
|
||||
|
||||
<Callout type="info" emoji="📦">
|
||||
DeerFlow Harness Python 包将以 <code>deerflow</code> 名称发布。目前尚未正式发布,安装方式<strong>即将推出</strong>。
|
||||
</Callout>
|
||||
|
||||
DeerFlow Harness 是构建自己 Super Agent 系统的 Python SDK 和运行时基础。
|
||||
|
||||
如果你想在自己的产品或工作流中整合技能、记忆、工具、沙箱和子 Agent 等 Agent 能力,这正是你需要的 DeerFlow 组件。
|
||||
|
||||
## 包名称
|
||||
|
||||
包名将是:
|
||||
|
||||
```bash
|
||||
pip install deerflow
|
||||
```
|
||||
|
||||
该包目前还未公开发布,但这是文档正式发布后将使用的安装路径。
|
||||
|
||||
## 当前状态
|
||||
|
||||
DeerFlow Harness 包**即将推出**。
|
||||
|
||||
目前,本章节的存在是为了建立 SDK 入口和包标识,同时公开分发流程正在最终确定中。
|
||||
|
||||
## Harness 将提供什么
|
||||
|
||||
Harness 专为想要在 DeerFlow 运行时模型之上构建自己 Agent 系统的开发者设计。
|
||||
|
||||
它将提供以下基础:
|
||||
|
||||
- 构建长时序 Agent
|
||||
- 组合运行时能力(记忆、工具、技能、子 Agent)
|
||||
- 在沙箱中执行 Agent
|
||||
- 通过配置和代码自定义 Agent 行为
|
||||
- 将 DeerFlow 集成到自己的应用架构中
|
||||
|
||||
## 下一步
|
||||
|
||||
在包正式发布之前,了解 DeerFlow Harness 的最佳方式是阅读本章节的概念和实现文档。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="快速上手" href="/docs/harness/quick-start" />
|
||||
<Cards.Card title="配置" href="/docs/harness/configuration" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,157 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# 集成指南
|
||||
|
||||
<Callout type="info" emoji="🔌">
|
||||
DeerFlow Harness 可以嵌入任何 Python 应用程序。本指南涵盖在你自己的系统中将 DeerFlow 作为库使用的集成模式。
|
||||
</Callout>
|
||||
|
||||
DeerFlow Harness 不仅仅是一个独立应用程序——它是一个可以导入并在你自己的后端、API 服务器、自动化系统或多 Agent 协调器中使用的 Python 库。
|
||||
|
||||
## 嵌入 DeerFlowClient
|
||||
|
||||
主要集成点是 `DeerFlowClient`。它封装了 LangGraph 运行时,并提供一个简洁的 API,用于在任何 Python 应用中发送消息和流式传输响应。
|
||||
|
||||
```python
|
||||
from deerflow.client import DeerFlowClient
|
||||
from deerflow.config import load_config
|
||||
|
||||
# 加载配置(读取 config.yaml 或 DEER_FLOW_CONFIG_PATH)
|
||||
load_config()
|
||||
|
||||
client = DeerFlowClient()
|
||||
```
|
||||
|
||||
客户端是线程安全的,设计为实例化一次并在请求之间复用。
|
||||
|
||||
## 异步流式传输
|
||||
|
||||
推荐的集成模式是异步流式传输。这让你可以在 Agent 生成响应时实时访问每个 token 和事件:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
|
||||
async def run_agent(thread_id: str, user_message: str):
|
||||
async for event in client.astream(
|
||||
thread_id=thread_id,
|
||||
message=user_message,
|
||||
config={
|
||||
"configurable": {
|
||||
"model_name": "gpt-4o",
|
||||
"subagent_enabled": True,
|
||||
}
|
||||
},
|
||||
):
|
||||
# 处理每个流式事件
|
||||
yield event
|
||||
|
||||
# 在 FastAPI 处理器中:
|
||||
# from fastapi.responses import StreamingResponse
|
||||
# return StreamingResponse(run_agent(thread_id, message), media_type="text/event-stream")
|
||||
```
|
||||
|
||||
## 非流式调用
|
||||
|
||||
对于批处理或只需要最终结果的场景:
|
||||
|
||||
```python
|
||||
async def run_agent_sync(thread_id: str, user_message: str) -> dict:
|
||||
result = await client.ainvoke(
|
||||
thread_id=thread_id,
|
||||
message=user_message,
|
||||
)
|
||||
return result
|
||||
```
|
||||
|
||||
## 线程管理
|
||||
|
||||
线程表示持久化对话。使用唯一线程 ID 隔离不同用户会话:
|
||||
|
||||
```python
|
||||
import uuid
|
||||
|
||||
# 新对话
|
||||
thread_id = str(uuid.uuid4())
|
||||
|
||||
# 继续已有对话(相同 thread_id)
|
||||
# 如果配置了检查点,Agent 将看到完整历史
|
||||
await client.ainvoke(thread_id=existing_thread_id, message="后续问题")
|
||||
```
|
||||
|
||||
## 自定义 Agent 配置
|
||||
|
||||
通过创建命名 Agent 配置并在运行时传入 `agent_name` 来构建领域特定 Agent:
|
||||
|
||||
```python
|
||||
# agents/research-assistant/config.yaml 必须存在并包含技能和工具配置
|
||||
|
||||
result = await client.ainvoke(
|
||||
thread_id=thread_id,
|
||||
message=user_message,
|
||||
config={
|
||||
"configurable": {
|
||||
"agent_name": "research-assistant",
|
||||
"model_name": "gpt-4o",
|
||||
}
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
## 与 FastAPI 集成
|
||||
|
||||
DeerFlow Gateway 本身是一个 FastAPI 应用程序。你可以将其作为子应用程序挂载:
|
||||
|
||||
```python
|
||||
from fastapi import FastAPI
|
||||
from deerflow.config import load_config
|
||||
|
||||
load_config()
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
# 挂载 DeerFlow Gateway
|
||||
from deerflow.app.gateway.main import app as gateway_app
|
||||
app.mount("/deerflow", gateway_app)
|
||||
```
|
||||
|
||||
或者在你自己的 FastAPI 路由中直接使用 `DeerFlowClient` 进行流式传输:
|
||||
|
||||
```python
|
||||
from fastapi import FastAPI
|
||||
from fastapi.responses import StreamingResponse
|
||||
from deerflow.client import DeerFlowClient
|
||||
|
||||
app = FastAPI()
|
||||
client = DeerFlowClient()
|
||||
|
||||
@app.post("/chat/{thread_id}")
|
||||
async def chat(thread_id: str, body: dict):
|
||||
async def generate():
|
||||
async for event in client.astream(thread_id=thread_id, message=body["message"]):
|
||||
yield f"data: {event}\n\n"
|
||||
return StreamingResponse(generate(), media_type="text/event-stream")
|
||||
```
|
||||
|
||||
## 嵌入模式下的配置
|
||||
|
||||
当嵌入到另一个应用程序时,显式设置配置路径以避免歧义:
|
||||
|
||||
```python
|
||||
import os
|
||||
os.environ["DEER_FLOW_CONFIG_PATH"] = "/path/to/my-deerflow-config.yaml"
|
||||
|
||||
from deerflow.config import load_config
|
||||
load_config()
|
||||
```
|
||||
|
||||
或直接传递路径:
|
||||
|
||||
```python
|
||||
from deerflow.config import load_config
|
||||
load_config(config_path="/path/to/my-deerflow-config.yaml")
|
||||
```
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="自定义与扩展" href="/docs/harness/customization" />
|
||||
<Cards.Card title="配置" href="/docs/harness/configuration" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,126 @@
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
|
||||
# Lead Agent
|
||||
|
||||
<Callout type="info" emoji="🧠">
|
||||
Lead Agent 是每个 DeerFlow 线程中的主要推理和编排单元。它决定要做什么、调用工具、委派子 Agent,并返回产出物。
|
||||
</Callout>
|
||||
|
||||
Lead Agent 是 DeerFlow 线程中的核心执行者。每个对话、任务和工作流都通过它进行。理解它的工作方式有助于你有效地配置它,并在需要时扩展它。
|
||||
|
||||
## Lead Agent 的职责
|
||||
|
||||
Lead Agent 负责:
|
||||
|
||||
- 接收用户消息并维护对话状态
|
||||
- 推断接下来要做什么(规划、工具选择、委派)
|
||||
- 调用工具——内置工具、社区工具、MCP 工具或技能工具
|
||||
- 通过 `task` 工具将子任务委派给子 Agent
|
||||
- 管理产出物(文件、输出、交付物)
|
||||
- 在计划模式下更新待办列表
|
||||
- 向用户返回最终响应或产出物
|
||||
|
||||
Lead Agent 不硬编码特定的工作流。它使用模型的推理能力来适应用户提供的任何任务,由系统提示和当前范围内的技能引导。
|
||||
|
||||
## 运行时基础
|
||||
|
||||
Lead Agent 基于 **LangGraph** 和 **LangChain Agent** 原语构建:
|
||||
|
||||
- `langchain.agents` 的 [`create_agent`](https://python.langchain.com/docs/concepts/agents/) 将 LLM 封装成工具调用 Agent 循环。
|
||||
- LangGraph 管理 `ThreadState`,提供检查点、流式传输和图执行模型。
|
||||
- **中间件链**包裹 Agent 循环的每一轮,提供记忆、摘要和澄清等跨领域能力。
|
||||
|
||||
## 执行流程
|
||||
|
||||
<Steps>
|
||||
|
||||
### 接收消息
|
||||
|
||||
用户消息到达并添加到 `ThreadState.messages`。`ThreadState` 保存完整的对话历史、任何活跃的待办列表、累积的产出物和运行时元数据。
|
||||
|
||||
### 中间件前处理
|
||||
|
||||
在调用模型之前,每个活跃的中间件都有机会修改状态。例如,`MemoryMiddleware` 将持久化的记忆事实注入到系统提示中,`SummarizationMiddleware` 在 token 预算超出时可能压缩旧消息。
|
||||
|
||||
### LLM 推理
|
||||
|
||||
模型接收当前消息(包括带有活跃技能指令的系统提示),并产生直接回复或一个或多个工具调用请求。
|
||||
|
||||
### 工具执行
|
||||
|
||||
如果请求了工具调用,它们会被分发到相应的处理器——用于文件和命令操作的沙箱工具、用于网络访问的社区工具,或用于子 Agent 委派的 `task` 工具。
|
||||
|
||||
### 中间件后处理
|
||||
|
||||
工具结果返回后、下一次模型调用之前,中间件再次运行。`TitleMiddleware` 可能在第一次交互后生成线程标题,`TodoMiddleware` 可能更新任务列表。
|
||||
|
||||
### 循环或响应
|
||||
|
||||
如果模型需要更多信息(例如,工具返回了部分结果),循环继续。当模型决定任务完成时,它产生最终消息,循环结束。
|
||||
|
||||
### 状态更新
|
||||
|
||||
`ThreadState` 更新为新消息、产出物和记忆队列。如果配置了检查点,状态将被持久化。
|
||||
|
||||
</Steps>
|
||||
|
||||
## 模型选择
|
||||
|
||||
Lead Agent 在运行时使用以下优先级顺序解析要使用的模型:
|
||||
|
||||
1. 每次请求配置中的 `model_name`(或 `model`),如果提供且有效。
|
||||
2. 活跃自定义 Agent 配置中的 `model` 字段,如果指定了 Agent。
|
||||
3. `config.yaml` 中 `models:` 列表的第一个模型(全局默认值)。
|
||||
|
||||
如果请求的模型名称在配置中找不到,系统回退到默认模型并记录警告。
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: my-primary-model
|
||||
use: langchain_openai:ChatOpenAI
|
||||
model: gpt-4o
|
||||
api_key: $OPENAI_API_KEY
|
||||
request_timeout: 600.0
|
||||
max_retries: 2
|
||||
supports_vision: true
|
||||
|
||||
- name: my-fast-model
|
||||
use: langchain_openai:ChatOpenAI
|
||||
model: gpt-4o-mini
|
||||
api_key: $OPENAI_API_KEY
|
||||
```
|
||||
|
||||
第一个条目(`my-primary-model`)成为默认值。任何不指定模型或指定未知模型名称的请求都将使用它。
|
||||
|
||||
## 思考模式
|
||||
|
||||
如果模型支持扩展思考(例如 DeepSeek Reasoner、启用思考的 Doubao、Anthropic Claude 思考模式),Lead Agent 可以在**思考模式**下运行。在此模式下,模型的内部推理步骤在响应流中可见。
|
||||
|
||||
思考模式通过每次请求的 `thinking_enabled` 标志控制。如果启用了思考但配置的模型不支持,系统会优雅地回退并记录警告。
|
||||
|
||||
## 计划模式
|
||||
|
||||
当请求配置中将 `is_plan_mode` 设为 `true` 时,`TodoMiddleware` 被激活。Agent 然后维护一个结构化的任务列表,在处理复杂任务时将条目标记为 `in_progress`、`completed` 或 `pending`。这为用户提供了 Agent 进度的可见性。
|
||||
|
||||
计划模式适用于显示增量进度有价值的复杂、多步骤任务。对于简单请求,最好禁用它以避免不必要的开销。
|
||||
|
||||
## 自定义 Agent
|
||||
|
||||
相同的 Lead Agent 运行时同时为默认 Agent 和你创建的任何自定义 Agent 提供服务。自定义 Agent 的区别仅在于:
|
||||
|
||||
- 其**名称**(ASCII slug,从 `display_name` 自动派生)
|
||||
- 其**系统提示**或 Agent 特定指令
|
||||
- 它有权访问的**技能**
|
||||
- 它可以使用的**工具组**
|
||||
- 它默认使用的**模型**
|
||||
|
||||
自定义 Agent 通过 DeerFlow 应用界面或 `/api/agents` 端点创建。其配置存储在后端目录的 `agents/{name}/config.yaml` 中。
|
||||
|
||||
<Callout type="tip">
|
||||
当在线程中选择自定义 Agent 时,Lead Agent 在运行时加载该 Agent 的配置。为特定 Agent 切换模型或技能不需要重启服务器。
|
||||
</Callout>
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="中间件" href="/docs/harness/middlewares" />
|
||||
<Cards.Card title="工具" href="/docs/harness/tools" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,103 @@
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
|
||||
# MCP 集成
|
||||
|
||||
<Callout type="info" emoji="🔌">
|
||||
Model Context Protocol(MCP)让 DeerFlow 能够连接任何外部工具服务器。连接后,MCP 工具与内置工具一样对 Lead Agent 可用。
|
||||
</Callout>
|
||||
|
||||
**Model Context Protocol(MCP)** 是连接语言模型与外部工具和数据源的开放标准。DeerFlow 的 MCP 集成允许你用任何实现了 MCP 协议的工具服务器扩展 Agent——无需修改 Harness 本身。
|
||||
|
||||
## 配置
|
||||
|
||||
MCP 服务器在 `extensions_config.json` 中配置,这个文件独立于 `config.yaml`。这种分离允许 MCP 和技能配置独立管理,并在运行时通过 Gateway API 更新。
|
||||
|
||||
默认位置是项目根目录(与 `config.yaml` 同一目录)。
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"my-server": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@my-org/my-mcp-server"],
|
||||
"enabled": true
|
||||
},
|
||||
"filesystem": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"],
|
||||
"enabled": true
|
||||
},
|
||||
"sqlite": {
|
||||
"command": "uvx",
|
||||
"args": ["mcp-server-sqlite", "--db-path", "/path/to/db.sqlite"],
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
每个服务器条目支持:
|
||||
- `command`:要运行的可执行文件(如 `npx`、`uvx`、`python`)
|
||||
- `args`:命令参数数组
|
||||
- `enabled`:服务器是否激活(可切换而无需删除条目)
|
||||
- `env`:可选地注入到服务器进程中的环境变量
|
||||
|
||||
## 工具如何加载
|
||||
|
||||
<Steps>
|
||||
|
||||
### 启动初始化
|
||||
|
||||
DeerFlow 服务器启动时调用 `initialize_mcp_tools()`。这连接到所有启用的 MCP 服务器,检索其工具 schema,并缓存结果。
|
||||
|
||||
### 缓存失效
|
||||
|
||||
MCP 工具缓存追踪 `extensions_config.json` 的修改时间(`mtime`)。当文件更改时——例如通过 Gateway API 启用或禁用服务器时——缓存被标记为过时,下次请求时重新加载工具。
|
||||
|
||||
这意味着 MCP 服务器更改无需重启 DeerFlow 服务器即可生效。
|
||||
|
||||
### 工具可用性
|
||||
|
||||
加载后,MCP 工具与内置和社区工具一起出现在 Lead Agent 的工具列表中。Agent 使用与其他工具相同的机制选择和调用它们。
|
||||
|
||||
</Steps>
|
||||
|
||||
## 工具搜索集成
|
||||
|
||||
当许多 MCP 服务器暴露大量工具时,预先将所有工具加载到 Agent 上下文中会增加 token 使用量并降低工具选择准确性。
|
||||
|
||||
启用**工具搜索**改为按需加载 MCP 工具:
|
||||
|
||||
```yaml
|
||||
# config.yaml
|
||||
tool_search:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
启用工具搜索后,MCP 工具按名称列在系统提示中,但不包含完整的工具 schema。Agent 使用 `tool_search` 内置工具发现它们,只将需要的工具加载到上下文中。
|
||||
|
||||
## OAuth 支持
|
||||
|
||||
某些 MCP 服务器需要 OAuth 认证。DeerFlow 的 `mcp/oauth.py` 处理声明了 OAuth 需求的服务器的 OAuth 流程。
|
||||
|
||||
当连接到受 OAuth 保护的 MCP 服务器时,DeerFlow 会:
|
||||
1. 从服务器能力头中检测 OAuth 需求
|
||||
2. 使用 `get_initial_oauth_headers()` 构建适当的授权头
|
||||
3. 通过 `build_oauth_tool_interceptor()` 用 OAuth 拦截器包装工具调用
|
||||
|
||||
OAuth 流程对 Lead Agent 是透明的——它只是调用工具,DeerFlow 处理认证。
|
||||
|
||||
## 管理 MCP 服务器
|
||||
|
||||
MCP 服务器可以通过多种方式管理:
|
||||
|
||||
- **通过 DeerFlow 应用界面**:扩展面板显示已连接的 MCP 服务器,允许你启用/禁用它们。
|
||||
- **通过 Gateway API**:`POST /api/extensions/mcp/{name}/enable` 和 `/disable`。
|
||||
- **直接编辑 `extensions_config.json`**:适用于脚本化或程序化配置。
|
||||
|
||||
由于基于文件 mtime 的缓存失效机制,更改会自动被检测到。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="工具" href="/docs/harness/tools" />
|
||||
<Cards.Card title="配置" href="/docs/harness/configuration" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,116 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# 记忆系统
|
||||
|
||||
<Callout type="info" emoji="💾">
|
||||
记忆让 DeerFlow 在多个会话中保留有用信息。Agent 记住用户偏好、项目背景和反复出现的事实,这样它可以在不每次从零开始的情况下给出更好的响应。
|
||||
</Callout>
|
||||
|
||||
记忆是 DeerFlow Harness 的一个运行时功能。它不是简单的对话日志,而是跨多个独立会话持久化、在未来对话中影响 Agent 行为的结构化事实和上下文摘要存储。
|
||||
|
||||
## 记忆存储什么
|
||||
|
||||
记忆存储包含几类信息:
|
||||
|
||||
- **工作上下文**:用户正在进行的项目摘要、目标和反复出现的话题。
|
||||
- **个人上下文**:Agent 学到的偏好、沟通风格和其他用户特定细节。
|
||||
- **近期关注**:最近的关注领域和活跃任务。
|
||||
- **历史**:近几个月的上下文、早期背景和长期事实。
|
||||
- **事实**:Agent 从对话中提取的离散具体事实(例如偏好的工具、团队名称、项目约束)。
|
||||
|
||||
每个类别随着 Agent 从持续对话中学习而随时间更新。
|
||||
|
||||
## 工作原理
|
||||
|
||||
记忆由 `MemoryMiddleware` 管理,在每次 Lead Agent 轮次上运行:
|
||||
|
||||
1. **注入**:每次对话开始时,Agent 当前记忆以受控的 token 预算(`max_injection_tokens`)注入到系统提示中。
|
||||
2. **学习**:对话结束后,后台任务提取新事实并更新相关记忆类别。更新通过 `debounce_seconds` 防抖以批量处理快速变化。
|
||||
3. **按 Agent 记忆**:当自定义 Agent 激活时,其记忆独立于全局记忆存储。这保持不同 Agent 的知识隔离。
|
||||
|
||||
## 配置
|
||||
|
||||
```yaml
|
||||
memory:
|
||||
enabled: true
|
||||
|
||||
# 全局记忆文件的存储路径。
|
||||
# 默认:{base_dir}/memory.json(解析为 backend/.deer-flow/memory.json)
|
||||
# 绝对路径按原样使用,相对路径相对于 base_dir 解析。
|
||||
storage_path: memory.json
|
||||
|
||||
# 存储类(默认:基于文件的 JSON 存储)
|
||||
storage_class: deerflow.agents.memory.storage.FileMemoryStorage
|
||||
|
||||
# 处理排队记忆更新前等待的秒数(防抖)
|
||||
debounce_seconds: 30
|
||||
|
||||
# 记忆更新提取使用的模型(null = 使用默认模型)
|
||||
model_name: null
|
||||
|
||||
# 要存储的最大事实数
|
||||
max_facts: 100
|
||||
|
||||
# 存储事实所需的最低置信度分数(0.0–1.0)
|
||||
fact_confidence_threshold: 0.7
|
||||
|
||||
# 是否将记忆注入到系统提示中
|
||||
injection_enabled: true
|
||||
|
||||
# 注入到系统提示的最大 token 数
|
||||
max_injection_tokens: 2000
|
||||
```
|
||||
|
||||
## 全局记忆与按 Agent 记忆
|
||||
|
||||
DeerFlow 支持两级记忆:
|
||||
|
||||
- **全局记忆**:存储在 `{base_dir}/memory.json`。在没有特定 Agent 激活或 Agent 没有按 Agent 记忆文件时使用。
|
||||
- **按 Agent 记忆**:存储在 `{base_dir}/agents/{agent_name}/memory.json`。当自定义 Agent 激活时使用,使该 Agent 学到的知识保持独立。
|
||||
|
||||
`MemoryMiddleware` 根据请求配置中的活跃 `agent_name` 自动选择正确的记忆文件。
|
||||
|
||||
用于记忆存储的 Agent 名称通过 `AGENT_NAME_PATTERN` 验证,以确保文件系统安全。
|
||||
|
||||
## 存储位置
|
||||
|
||||
默认情况下,记忆文件存储在后端基础目录下:
|
||||
|
||||
- 基础目录:`backend/.deer-flow/`
|
||||
- 全局记忆:`backend/.deer-flow/memory.json`
|
||||
- 按 Agent 记忆:`backend/.deer-flow/agents/{agent_name}/memory.json`
|
||||
|
||||
你可以用 `storage_path` 字段更改存储路径。相对路径相对于基础目录解析;使用绝对路径可以将记忆存储在自定义位置。
|
||||
|
||||
## 自定义存储后端
|
||||
|
||||
`storage_class` 字段允许你用自定义实现替换默认的基于文件的存储。任何继承 `MemoryStorage` 并实现 `load()`、`reload()` 和 `save()` 方法的类都可以使用:
|
||||
|
||||
```yaml
|
||||
memory:
|
||||
storage_class: mypackage.storage.RedisMemoryStorage
|
||||
```
|
||||
|
||||
如果配置的类无法加载,系统回退到默认的 `FileMemoryStorage` 并记录错误。
|
||||
|
||||
## 禁用记忆
|
||||
|
||||
完全禁用记忆:
|
||||
|
||||
```yaml
|
||||
memory:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
保留记忆存储但阻止注入到系统提示:
|
||||
|
||||
```yaml
|
||||
memory:
|
||||
enabled: true
|
||||
injection_enabled: false
|
||||
```
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="配置" href="/docs/harness/configuration" />
|
||||
<Cards.Card title="中间件" href="/docs/harness/middlewares" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,196 @@
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 中间件
|
||||
|
||||
<Callout type="info" emoji="🔌">
|
||||
中间件包裹 Lead Agent 中的每次 LLM 调用。它们是添加跨领域行为(如记忆、摘要压缩、澄清和 token 追踪)的主要扩展点。
|
||||
</Callout>
|
||||
|
||||
每次 Lead Agent 调用 LLM 时,都会先后执行一条**中间件链**。中间件可以读取和修改 Agent 的状态、向系统提示注入内容、拦截工具调用,并对模型输出做出反应。
|
||||
|
||||
这种设计使 Agent 核心保持简单稳定,同时允许丰富的可组合行为分层叠加。
|
||||
|
||||
## 链的工作方式
|
||||
|
||||
中间件链在每次 Agent 调用时根据当前配置和请求参数构建一次。中间件按定义的顺序运行:
|
||||
|
||||
1. 运行时中间件(错误处理、线程数据、上传、悬空工具调用修补)
|
||||
2. `SummarizationMiddleware` — 上下文压缩(如果启用)
|
||||
3. `TodoMiddleware` — 任务列表管理(仅计划模式)
|
||||
4. `TokenUsageMiddleware` — token 追踪(如果启用)
|
||||
5. `TitleMiddleware` — 自动生成线程标题
|
||||
6. `MemoryMiddleware` — 跨会话记忆注入和队列
|
||||
7. `ViewImageMiddleware` — 图像细节注入(如果模型支持视觉)
|
||||
8. `DeferredToolFilterMiddleware` — 隐藏延迟工具 schema(如果启用工具搜索)
|
||||
9. `SubagentLimitMiddleware` — 限制并行子 Agent 调用(如果启用子 Agent)
|
||||
10. `LoopDetectionMiddleware` — 打破重复工具调用循环
|
||||
11. 自定义中间件(如有)
|
||||
12. `ClarificationMiddleware` — 拦截澄清请求(始终最后)
|
||||
|
||||
顺序很重要。摘要压缩在早期运行以在其他处理之前减少上下文。澄清总是最后运行,这样它可以在所有其他中间件完成后拦截。
|
||||
|
||||
## 中间件参考
|
||||
|
||||
### ClarificationMiddleware
|
||||
|
||||
拦截澄清工具调用,并将其转换为面向用户的信息请求。当模型决定在继续之前需要询问用户某事时,此中间件会将该请求呈现出来。
|
||||
|
||||
**配置**:由 `guardrails.clarification` 设置控制。
|
||||
|
||||
---
|
||||
|
||||
### LoopDetectionMiddleware
|
||||
|
||||
检测 Agent 是否在没有取得进展的情况下重复进行相同的工具调用。检测到循环时,中间件会介入打破循环,防止 Agent 无限消耗轮次。
|
||||
|
||||
**配置**:内置,无需用户配置。
|
||||
|
||||
---
|
||||
|
||||
### MemoryMiddleware
|
||||
|
||||
在每次对话开始时读取持久化记忆事实并将其注入到系统提示中。对话结束后,将后台更新排队,以将新信息纳入记忆存储。
|
||||
|
||||
**配置**:参见[记忆系统](/docs/harness/memory)页面和 `config.yaml` 中的 `memory:` 部分。
|
||||
|
||||
```yaml
|
||||
memory:
|
||||
enabled: true
|
||||
injection_enabled: true
|
||||
max_injection_tokens: 2000
|
||||
debounce_seconds: 30
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### SubagentLimitMiddleware
|
||||
|
||||
限制 Agent 在单次轮次中可以进行的并行子 Agent 任务调用数量。这防止 Agent 生成无限数量的并发子 Agent。
|
||||
|
||||
**配置**:每次请求配置中的 `subagent_enabled` 和 `max_concurrent_subagents`。
|
||||
|
||||
---
|
||||
|
||||
### TitleMiddleware
|
||||
|
||||
在第一次交互后自动为线程生成标题。标题从用户的第一条消息和 Agent 的响应中派生。
|
||||
|
||||
**配置**:`config.yaml` 中的 `title:` 部分。
|
||||
|
||||
```yaml
|
||||
title:
|
||||
enabled: true
|
||||
max_words: 6
|
||||
max_chars: 60
|
||||
model_name: null # 使用默认模型
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### TodoMiddleware
|
||||
|
||||
当计划模式激活时,维护一个对用户可见的结构化任务列表。Agent 使用 `write_todos` 工具,随着完成复杂目标,将任务标记为 `pending`、`in_progress` 或 `completed`。
|
||||
|
||||
**激活**:在请求配置中设置 `is_plan_mode: true` 时自动启用。不需要 `config.yaml` 条目。
|
||||
|
||||
---
|
||||
|
||||
### TokenUsageMiddleware
|
||||
|
||||
追踪每次模型调用的 LLM token 消耗,并以 `info` 级别记录。对于监控成本和了解长时序任务中 token 的使用位置很有帮助。
|
||||
|
||||
**配置**:`config.yaml` 中的 `token_usage:` 部分。
|
||||
|
||||
```yaml
|
||||
token_usage:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### SummarizationMiddleware
|
||||
|
||||
当对话变长时,对旧消息进行摘要以减少上下文大小。摘要被注入回对话,替代原始消息,在不需要完整 token 成本的情况下保留含义。
|
||||
|
||||
**配置**:`config.yaml` 中的 `summarization:` 部分。详见下方详细配置。
|
||||
|
||||
---
|
||||
|
||||
### ViewImageMiddleware
|
||||
|
||||
当当前模型支持视觉(`supports_vision: true`)时,此中间件拦截 `view_image` 工具调用,并将图像内容直接注入到模型的上下文中以便分析。
|
||||
|
||||
**激活**:当解析的模型具有 `supports_vision: true` 时自动启用。
|
||||
|
||||
---
|
||||
|
||||
### DeferredToolFilterMiddleware
|
||||
|
||||
当工具搜索启用时,此中间件从模型上下文中隐藏延迟工具 schema。工具通过 `tool_search` 工具按需发现,而不是预先全部列出,从而减少上下文使用。
|
||||
|
||||
**配置**:`config.yaml` 中的 `tool_search.enabled: true`。
|
||||
|
||||
## 摘要压缩配置详解
|
||||
|
||||
`SummarizationMiddleware` 是长时序任务中影响最大的中间件之一。完整配置参考如下:
|
||||
|
||||
```yaml
|
||||
summarization:
|
||||
enabled: true
|
||||
|
||||
# 摘要使用的模型(null = 使用默认模型)
|
||||
# 推荐使用轻量级、经济的模型,如 "gpt-4o-mini"
|
||||
model_name: null
|
||||
|
||||
# 触发条件——满足任意一个条件时运行摘要
|
||||
trigger:
|
||||
- type: tokens # 当上下文超过 N 个 token 时触发
|
||||
value: 15564
|
||||
# - type: messages # 当消息数超过 N 时触发
|
||||
# value: 50
|
||||
# - type: fraction # 当上下文达到模型最大输入的 X% 时触发
|
||||
# value: 0.8
|
||||
|
||||
# 摘要后保留多少最近历史
|
||||
keep:
|
||||
type: messages
|
||||
value: 10 # 保留最近 10 条消息
|
||||
# 或者按 token 保留:
|
||||
# type: tokens
|
||||
# value: 3000
|
||||
|
||||
# 为摘要器准备消息时要裁剪的最大 token 数
|
||||
trim_tokens_to_summarize: 15564
|
||||
|
||||
# 自定义摘要提示词(null = 使用默认 LangChain 提示词)
|
||||
summary_prompt: null
|
||||
```
|
||||
|
||||
**触发类型**:
|
||||
- `tokens`:当对话中总 token 数超过 `value` 时触发。
|
||||
- `messages`:当消息数超过 `value` 时触发。
|
||||
- `fraction`:当上下文达到模型最大输入 token 限制的 `value` 比例时触发。
|
||||
|
||||
**保留类型**:
|
||||
- `messages`:摘要后保留最后 `value` 条消息。
|
||||
- `tokens`:保留最近 `value` 个 token 的历史。
|
||||
- `fraction`:保留模型最大输入 token 限制的 `value` 比例的最近历史。
|
||||
|
||||
## 编写自定义中间件
|
||||
|
||||
自定义中间件可以注入到链中用于专业用途。中间件必须实现 `langchain.agents.middleware` 中的 `AgentMiddleware` 接口:
|
||||
|
||||
```python
|
||||
from langchain.agents.middleware import AgentMiddleware
|
||||
|
||||
class MyMiddleware(AgentMiddleware):
|
||||
async def on_start(self, state, config):
|
||||
# 在模型调用前运行
|
||||
return state, config
|
||||
|
||||
async def on_end(self, state, config):
|
||||
# 在模型调用后运行
|
||||
return state, config
|
||||
```
|
||||
|
||||
自定义中间件在链末尾 `ClarificationMiddleware` 之前注入。
|
||||
@@ -0,0 +1,151 @@
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
|
||||
# 快速上手
|
||||
|
||||
<Callout type="info" emoji="🚀">
|
||||
本指南介绍如何以编程方式使用 DeerFlow Harness——不是通过应用界面,而是直接在 Python 中导入和调用 Harness。
|
||||
</Callout>
|
||||
|
||||
DeerFlow Harness 是 Python SDK 和运行时基础。本快速上手指南将带你了解运行 Agent、流式传输输出和使用线程的核心 API。
|
||||
|
||||
## 前置条件
|
||||
|
||||
DeerFlow Harness 需要 Python 3.12 或更高版本。该包是 `deerflow` 代码库的一部分,位于 `backend/packages/harness` 下。
|
||||
|
||||
如果你从仓库克隆开始:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
uv sync
|
||||
```
|
||||
|
||||
## 配置
|
||||
|
||||
所有 Harness 行为由 `config.yaml` 驱动。至少需要配置一个模型:
|
||||
|
||||
```yaml
|
||||
# config.yaml
|
||||
config_version: 6
|
||||
|
||||
models:
|
||||
- name: gpt-4o
|
||||
use: langchain_openai:ChatOpenAI
|
||||
model: gpt-4o
|
||||
api_key: $OPENAI_API_KEY
|
||||
request_timeout: 600.0
|
||||
max_retries: 2
|
||||
|
||||
sandbox:
|
||||
use: deerflow.sandbox.local:LocalSandboxProvider
|
||||
|
||||
tools:
|
||||
- use: deerflow.community.ddg_search.tools:web_search_tool
|
||||
- use: deerflow.community.jina_ai.tools:web_fetch_tool
|
||||
- use: deerflow.sandbox.tools:ls_tool
|
||||
- use: deerflow.sandbox.tools:read_file_tool
|
||||
- use: deerflow.sandbox.tools:write_file_tool
|
||||
- use: deerflow.sandbox.tools:bash_tool
|
||||
```
|
||||
|
||||
将 `config.example.yaml` 复制到 `config.yaml` 并填写你的 API Key。
|
||||
|
||||
## 运行 Harness
|
||||
|
||||
DeerFlow Harness 的主要入口是 `DeerFlowClient`。它管理线程状态、调用 Lead Agent,并流式传输响应。
|
||||
|
||||
<Steps>
|
||||
|
||||
### 导入并配置
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from deerflow.client import DeerFlowClient
|
||||
from deerflow.config import load_config
|
||||
|
||||
# 从当前目录或 DEER_FLOW_CONFIG_PATH 加载 config.yaml
|
||||
load_config()
|
||||
|
||||
client = DeerFlowClient()
|
||||
```
|
||||
|
||||
### 创建线程
|
||||
|
||||
```python
|
||||
thread_id = "my-thread-001"
|
||||
```
|
||||
|
||||
线程 ID 是任意字符串。使用相同 ID 可以继续已有对话(需要配置检查点)。
|
||||
|
||||
### 发送消息并流式传输响应
|
||||
|
||||
```python
|
||||
async def run():
|
||||
async for event in client.astream(
|
||||
thread_id=thread_id,
|
||||
message="研究前三大开源 LLM 框架并进行总结。",
|
||||
config={
|
||||
"configurable": {
|
||||
"model_name": "gpt-4o",
|
||||
"thinking_enabled": False,
|
||||
"is_plan_mode": True,
|
||||
"subagent_enabled": True,
|
||||
}
|
||||
},
|
||||
):
|
||||
print(event)
|
||||
|
||||
asyncio.run(run())
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
## 可配置选项
|
||||
|
||||
`config.configurable` 字典控制每次请求的行为:
|
||||
|
||||
| 键 | 类型 | 默认值 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `model_name` | `str \| None` | 配置中第一个模型 | 本次请求使用的模型 |
|
||||
| `thinking_enabled` | `bool` | `True` | 启用扩展思考模式(如果支持) |
|
||||
| `reasoning_effort` | `str \| None` | `None` | 推理努力程度(特定模型参数) |
|
||||
| `is_plan_mode` | `bool` | `False` | 启用 TodoList 中间件进行任务跟踪 |
|
||||
| `subagent_enabled` | `bool` | `False` | 允许 Agent 委派子任务 |
|
||||
| `max_concurrent_subagents` | `int` | `3` | 每轮最大并行子 Agent 调用数 |
|
||||
| `agent_name` | `str \| None` | `None` | 要加载的自定义 Agent 名称 |
|
||||
|
||||
## 流式事件类型
|
||||
|
||||
`client.astream()` 从 LangGraph 运行时产生事件,主要事件类型如下:
|
||||
|
||||
| 事件类型 | 说明 |
|
||||
|---|---|
|
||||
| `messages` | 消息块(文本、思考过程、工具调用) |
|
||||
| `thread_state` | 线程状态更新(标题、产出物、待办列表) |
|
||||
|
||||
消息块包含 Agent 生成响应时的 token 流。
|
||||
|
||||
## 使用自定义 Agent
|
||||
|
||||
如果已定义自定义 Agent,在 configurable 中传入其 `name`:
|
||||
|
||||
```python
|
||||
async for event in client.astream(
|
||||
thread_id="thread-002",
|
||||
message="分析上传的 CSV 并生成摘要图表。",
|
||||
config={
|
||||
"configurable": {
|
||||
"agent_name": "data-analyst",
|
||||
"subagent_enabled": True,
|
||||
}
|
||||
},
|
||||
):
|
||||
...
|
||||
```
|
||||
|
||||
自定义 Agent 的配置(模型、技能、工具组)将从 `agents/data-analyst/config.yaml` 自动加载。
|
||||
|
||||
<Cards num={3}>
|
||||
<Cards.Card title="设计理念" href="/docs/harness/design-principles" />
|
||||
<Cards.Card title="Lead Agent" href="/docs/harness/lead-agent" />
|
||||
<Cards.Card title="配置" href="/docs/harness/configuration" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,139 @@
|
||||
import { Callout, Cards, Tabs } from "nextra/components";
|
||||
|
||||
# 沙箱
|
||||
|
||||
<Callout type="info" emoji="📦">
|
||||
沙箱是 Agent 进行文件和命令操作的隔离工作区。它让 DeerFlow 能够采取真实行动,而不仅仅是对话。
|
||||
</Callout>
|
||||
|
||||
沙箱为 Lead Agent 提供一个受控环境,在其中可以读取文件、写入输出、运行 Shell 命令并生成产出物。没有沙箱,Agent 只能生成文本;有了沙箱,它可以编写和执行代码、处理数据文件、生成图表并构建交付物。
|
||||
|
||||
## 沙箱模式
|
||||
|
||||
DeerFlow 支持三种沙箱模式,选择适合你部署的一种:
|
||||
|
||||
### LocalSandbox(默认)
|
||||
|
||||
命令直接在主机机器的文件系统上运行,没有容器隔离。
|
||||
|
||||
- **适合**:受信任的单用户本地开发工作流。
|
||||
- **风险**:Agent 可以访问主机文件系统。默认使用 `allow_host_bash: false` 防止任意命令执行。
|
||||
|
||||
```yaml
|
||||
sandbox:
|
||||
use: deerflow.sandbox.local:LocalSandboxProvider
|
||||
allow_host_bash: false # 默认;仅对完全受信任的工作流设置为 true
|
||||
```
|
||||
|
||||
### 基于容器的 AIO 沙箱
|
||||
|
||||
命令在隔离容器中运行(Linux/Windows 上的 Docker,macOS 上的 Apple Container)。每个沙箱会话获得一个全新的容器环境。
|
||||
|
||||
- **适合**:多用户环境、生产部署,或任何需要执行隔离的场景。
|
||||
|
||||
```yaml
|
||||
sandbox:
|
||||
use: deerflow.community.aio_sandbox:AioSandboxProvider
|
||||
|
||||
# 可选:容器镜像(下方显示默认值)
|
||||
image: enterprise-public-cn-beijing.cr.volces.com/vefaas-public/all-in-one-sandbox:latest
|
||||
|
||||
# 可选:最大并发容器数(默认:3,超出时 LRU 淘汰)
|
||||
replicas: 3
|
||||
|
||||
# 可选:空闲超时(秒,默认:600)
|
||||
idle_timeout: 600
|
||||
|
||||
# 可选:自定义挂载
|
||||
mounts:
|
||||
- host_path: /path/on/host
|
||||
container_path: /home/user/shared
|
||||
read_only: false
|
||||
```
|
||||
|
||||
安装:`cd backend && uv add 'deerflow-harness[aio-sandbox]'`
|
||||
|
||||
### Provisioner 管理的沙箱(Kubernetes)
|
||||
|
||||
每个沙箱在 Kubernetes 集群中获得一个专用 Pod,由 Provisioner 服务管理。这提供最强的隔离性,适合有多个并发用户的生产环境。
|
||||
|
||||
```yaml
|
||||
sandbox:
|
||||
use: deerflow.community.aio_sandbox:AioSandboxProvider
|
||||
provisioner_url: http://provisioner:8002
|
||||
```
|
||||
|
||||
## 路径映射
|
||||
|
||||
沙箱使用路径映射来桥接主机文件系统和容器的虚拟文件系统。始终配置两个关键映射:
|
||||
|
||||
| 主机路径 | 容器路径 | 访问权限 |
|
||||
|---|---|---|
|
||||
| `skills/`(来自 `skills.path`) | `/mnt/skills`(来自 `skills.container_path`) | 只读 |
|
||||
| `.deer-flow/threads/{thread_id}/user-data/` | `/mnt/user-data/` | 读写 |
|
||||
|
||||
技能目录始终以只读方式挂载。线程将其工作数据(上传文件、输出、中间文件)写入 `/mnt/user-data/`。
|
||||
|
||||
### 自定义挂载
|
||||
|
||||
你可以为本地沙箱使用 `mounts:` 配置添加额外挂载:
|
||||
|
||||
```yaml
|
||||
sandbox:
|
||||
use: deerflow.sandbox.local:LocalSandboxProvider
|
||||
mounts:
|
||||
- host_path: /home/user/my-project
|
||||
container_path: /mnt/my-project
|
||||
read_only: true
|
||||
```
|
||||
|
||||
<Callout type="warning">
|
||||
自定义挂载的 <code>container_path</code> 不能与保留前缀冲突:
|
||||
<code>/mnt/skills</code>、<code>/mnt/acp-workspace</code> 或 <code>/mnt/user-data</code>。
|
||||
</Callout>
|
||||
|
||||
## 输出截断
|
||||
|
||||
沙箱工具限制输出大小以保持 Agent 上下文可控。这些限制可配置:
|
||||
|
||||
```yaml
|
||||
sandbox:
|
||||
use: deerflow.sandbox.local:LocalSandboxProvider
|
||||
|
||||
# bash 使用中间截断(头部 + 尾部)
|
||||
bash_output_max_chars: 20000
|
||||
|
||||
# read_file 使用头部截断
|
||||
read_file_output_max_chars: 50000
|
||||
|
||||
# ls 使用头部截断
|
||||
ls_output_max_chars: 20000
|
||||
```
|
||||
|
||||
设置为 `0` 禁用截断。
|
||||
|
||||
## 安全性
|
||||
|
||||
### LocalSandbox
|
||||
|
||||
`LocalSandbox` 直接在主机上运行命令。默认情况下,`bash` 工具**被禁用**以防止任意主机命令执行。仅对完全受信任的单用户工作流启用它:
|
||||
|
||||
```yaml
|
||||
sandbox:
|
||||
allow_host_bash: true # 危险:授予 Agent 对你机器的 Shell 访问权限
|
||||
```
|
||||
|
||||
即使没有 `bash`,Agent 也可以通过专用文件工具读写文件。
|
||||
|
||||
### 容器沙箱
|
||||
|
||||
基于容器的沙箱提供文件系统和进程隔离。Agent 看不到或修改主机文件系统,除非通过显式挂载。Provisioner 管理模式增加了额外一层:每个线程获得自己的隔离 Pod。
|
||||
|
||||
### 审计中间件
|
||||
|
||||
`SandboxAuditMiddleware` 在每次 Agent 轮次上运行,记录所有沙箱操作,提供会话期间访问了哪些文件、运行了哪些命令的审计跟踪。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="工具" href="/docs/harness/tools" />
|
||||
<Cards.Card title="子 Agent" href="/docs/harness/subagents" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,151 @@
|
||||
import { Callout, Cards, FileTree, Steps } from "nextra/components";
|
||||
|
||||
# 技能
|
||||
|
||||
<Callout type="info" emoji="🎯">
|
||||
技能是面向任务的能力包,教会 Agent 如何完成特定类型的工作。基础 Agent 保持通用;技能在需要时提供专业化。
|
||||
</Callout>
|
||||
|
||||
技能不仅仅是提示词。它是一个自包含的能力包,可以包含结构化指令、分步工作流、领域最佳实践、支撑资源和工具配置。技能按需加载——在任务需要时注入内容,否则不影响上下文。
|
||||
|
||||
## 技能包含什么
|
||||
|
||||
每个技能位于 `skills/public/`(或用户创建技能的 `skills/custom/`)下自己的子目录中。目录包含一个 `SKILL.md` 文件,定义技能的元数据、指令和工作流。
|
||||
|
||||
<FileTree>
|
||||
<FileTree.Folder name="skills/" defaultOpen>
|
||||
<FileTree.Folder name="public/" defaultOpen>
|
||||
<FileTree.Folder name="deep-research/" defaultOpen>
|
||||
<FileTree.File name="SKILL.md" />
|
||||
</FileTree.Folder>
|
||||
<FileTree.Folder name="data-analysis/">
|
||||
<FileTree.File name="SKILL.md" />
|
||||
</FileTree.Folder>
|
||||
</FileTree.Folder>
|
||||
<FileTree.Folder name="custom/">
|
||||
<FileTree.File name="(你的自定义技能放在这里)" />
|
||||
</FileTree.Folder>
|
||||
</FileTree.Folder>
|
||||
</FileTree>
|
||||
|
||||
`SKILL.md` 文件是技能的权威定义,由 `skills/parser.py` 解析以提取技能名称、描述、类别、指令以及任何依赖项或工具需求。
|
||||
|
||||
## 内置技能
|
||||
|
||||
DeerFlow 内置以下公共技能:
|
||||
|
||||
| 技能 | 描述 |
|
||||
|---|---|
|
||||
| `deep-research` | 带来源收集、交叉验证和结构化输出的多步骤研究 |
|
||||
| `data-analysis` | 数据探索、统计分析和洞察生成 |
|
||||
| `chart-visualization` | 从数据创建图表和可视化 |
|
||||
| `ppt-generation` | 演示文稿幻灯片生成 |
|
||||
| `image-generation` | AI 图像生成工作流 |
|
||||
| `code-documentation` | 自动化代码文档生成 |
|
||||
| `newsletter-generation` | 新闻简报内容创作 |
|
||||
| `podcast-generation` | 播客脚本和大纲生成 |
|
||||
| `academic-paper-review` | 结构化学术论文分析 |
|
||||
| `consulting-analysis` | 商业咨询框架和分析 |
|
||||
| `systematic-literature-review` | 文献综述方法论和综合 |
|
||||
| `github-deep-research` | 仓库和代码深度研究 |
|
||||
| `frontend-design` | 前端设计和 UI 工作流 |
|
||||
| `web-design-guidelines` | 网页设计标准和审查 |
|
||||
| `video-generation` | 视频内容规划和生成 |
|
||||
|
||||
## 技能生命周期
|
||||
|
||||
<Steps>
|
||||
|
||||
### 发现和加载
|
||||
|
||||
`skills/loader.py` 中的 `load_skills()` 扫描配置技能路径下的 `public/` 和 `custom/` 目录。它每次调用都重新读取 `ExtensionsConfig.from_file()`,这意味着通过 Gateway API 启用或禁用技能会立即在运行中的 LangGraph 服务器中生效,无需重启。
|
||||
|
||||
### 解析
|
||||
|
||||
`parser.py` 读取每个 `SKILL.md` 文件并提取结构化元数据:名称、描述、类别、指令以及任何工具或资源需求。
|
||||
|
||||
### 安全扫描
|
||||
|
||||
`security_scanner.py` 在技能内容加载到 Agent 上下文之前检查潜在危险模式,防止恶意技能内容被注入。
|
||||
|
||||
### 依赖安装
|
||||
|
||||
`installer.py` 处理技能声明的任何 Python 或系统依赖项,在技能首次加载时安装到运行时环境中。
|
||||
|
||||
### 上下文注入
|
||||
|
||||
当 Agent 以特定技能在范围内调用时,技能的指令被注入到系统提示中。Agent 在该对话期间可以访问技能的工作流、最佳实践和领域知识。
|
||||
|
||||
</Steps>
|
||||
|
||||
## 配置
|
||||
|
||||
技能系统在 `config.yaml` 的 `skills:` 下配置:
|
||||
|
||||
```yaml
|
||||
skills:
|
||||
# 主机上的技能目录路径。
|
||||
# 默认:相对于后端目录的 ../skills
|
||||
# 取消注释以自定义:
|
||||
# path: /absolute/path/to/custom/skills
|
||||
|
||||
# 在沙箱容器中挂载技能的路径
|
||||
container_path: /mnt/skills
|
||||
```
|
||||
|
||||
`container_path` 很重要:它告诉 Agent 在沙箱内哪里找到技能文件。Harness 自动将主机技能目录挂载到这个容器路径。
|
||||
|
||||
## 启用和禁用技能
|
||||
|
||||
技能可用性在 `extensions_config.json` 中跟踪(独立于 `config.yaml`)。你可以管理技能状态:
|
||||
|
||||
- **通过 DeerFlow 应用界面**:技能面板允许你切换技能的启用/禁用状态。
|
||||
- **通过 Gateway API**:`POST /api/extensions/skills/{name}/enable` 和 `/disable`。
|
||||
- **直接编辑 `extensions_config.json`**。
|
||||
|
||||
由于 `load_skills()` 每次调用都重新读取扩展配置,更改立即生效——无需重启服务器。
|
||||
|
||||
## 按自定义 Agent 限制技能
|
||||
|
||||
自定义 Agent 可以被限制为特定技能子集。在 Agent 的配置中(存储在 `agents/{name}/config.yaml`),设置 `skills` 列表:
|
||||
|
||||
```yaml
|
||||
# agents/my-researcher/config.yaml
|
||||
name: my-researcher
|
||||
skills:
|
||||
- deep-research
|
||||
- academic-paper-review
|
||||
```
|
||||
|
||||
- **省略或 null**:Agent 加载所有全局启用的技能。
|
||||
- **空列表 `[]`**:Agent 没有技能。
|
||||
- **命名列表**:Agent 只加载那些特定技能。
|
||||
|
||||
## 技能进化
|
||||
|
||||
DeerFlow 包含一个可选的**技能进化**功能,允许 Agent 在 `skills/custom/` 目录中自主创建和改进技能:
|
||||
|
||||
```yaml
|
||||
skill_evolution:
|
||||
enabled: false # 设为 true 允许 Agent 管理技能创建
|
||||
moderation_model_name: null # 安全扫描模型(null = 使用默认模型)
|
||||
```
|
||||
|
||||
<Callout type="warning">
|
||||
只在你信任 Agent 输出的环境中启用技能进化。新创建的技能在加载前会经过安全扫描,但该功能给予 Agent 对技能目录的写访问权限。
|
||||
</Callout>
|
||||
|
||||
## 编写自定义技能
|
||||
|
||||
要创建自定义技能:
|
||||
|
||||
1. 在 `skills/custom/your-skill-name/` 下创建新目录
|
||||
2. 添加定义技能元数据和指令的 `SKILL.md` 文件
|
||||
3. 技能将在下次 `load_skills()` 调用时自动被发现
|
||||
|
||||
`SKILL.md` 格式遵循与内置技能相同的结构。使用现有公共技能之一作为预期格式的参考。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="沙箱" href="/docs/harness/sandbox" />
|
||||
<Cards.Card title="工具" href="/docs/harness/tools" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,119 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# 子 Agent
|
||||
|
||||
<Callout type="info" emoji="👥">
|
||||
子 Agent 是 Lead Agent 委派子任务的专注执行者。它们以隔离的上下文运行,在处理并行或专业工作的同时保持主对话清晰。
|
||||
</Callout>
|
||||
|
||||
当一个任务对单个推理线程来说太宽泛,或者部分任务可以并行完成时,Lead Agent 将工作委派给**子 Agent**。子 Agent 是一个独立的 Agent 调用,接收特定任务、执行并返回结果。
|
||||
|
||||
## 为什么子 Agent 很重要
|
||||
|
||||
子 Agent 解决了长时序工作流中的两个关键问题:
|
||||
|
||||
1. **上下文隔离**:子 Agent 只看到完成其任务所需的信息,而不是整个父对话。这保持了每个 Agent 的工作上下文专注且可控。
|
||||
2. **并行性**:多个子 Agent 可以并发运行,允许任务的独立部分(例如同时研究多个话题)并行处理。
|
||||
|
||||
## 内置子 Agent
|
||||
|
||||
DeerFlow 内置两个子 Agent:
|
||||
|
||||
### general-purpose
|
||||
|
||||
通用推理和执行 Agent,适合委派需要多步骤推理、网络搜索、文件操作和产出物生成的复杂子任务。
|
||||
|
||||
- **默认超时**:900 秒(15 分钟)
|
||||
- **默认最大轮次**:160
|
||||
|
||||
### bash
|
||||
|
||||
专门用于在沙箱内执行命令行任务的子 Agent,适合脚本编写、数据处理、文件转换和环境设置任务。
|
||||
|
||||
- **默认超时**:900 秒(15 分钟)
|
||||
- **默认最大轮次**:80
|
||||
- **可用性**:仅当沙箱的 `bash` 工具可用时才暴露(`allow_host_bash: true` 或配置了容器沙箱)
|
||||
|
||||
## 委派流程
|
||||
|
||||
Lead Agent 使用内置 `task` 工具将工作委派给子 Agent:
|
||||
|
||||
```
|
||||
task(
|
||||
agent="general-purpose",
|
||||
task="研究 Acme Corp 的前 5 个竞争对手并总结其定价",
|
||||
context="专注于 B2B SaaS 定价模型"
|
||||
)
|
||||
```
|
||||
|
||||
运行时然后:
|
||||
|
||||
1. 从注册表查找子 Agent 配置,应用任何 `config.yaml` 覆盖。
|
||||
2. 用子 Agent 自己的提示词和工具创建新的 Agent 调用。
|
||||
3. 将子 Agent 运行到完成(或直到超时/最大轮次)。
|
||||
4. 将子 Agent 的最终输出作为工具结果返回给 Lead Agent。
|
||||
|
||||
## 配置
|
||||
|
||||
子 Agent 超时和最大轮次通过 `config.yaml` 中的 `subagents:` 部分控制:
|
||||
|
||||
```yaml
|
||||
subagents:
|
||||
# 所有子 Agent 的默认超时(秒,默认:900 = 15 分钟)
|
||||
timeout_seconds: 900
|
||||
|
||||
# 可选:覆盖所有子 Agent 的最大轮次
|
||||
# max_turns: 120
|
||||
|
||||
# 可选:按 Agent 覆盖
|
||||
agents:
|
||||
general-purpose:
|
||||
timeout_seconds: 1800 # 复杂任务 30 分钟
|
||||
max_turns: 160
|
||||
bash:
|
||||
timeout_seconds: 300 # 快速命令 5 分钟
|
||||
max_turns: 80
|
||||
```
|
||||
|
||||
按 Agent 覆盖优先于全局 `timeout_seconds` 和 `max_turns` 设置。
|
||||
|
||||
## 并发限制
|
||||
|
||||
`SubagentLimitMiddleware` 控制 Lead Agent 在单次轮次中可以并行调用多少个子 Agent,通过每次请求的配置控制:
|
||||
|
||||
- `subagent_enabled`:是否为此会话激活子 Agent 委派
|
||||
- `max_concurrent_subagents`:单次轮次中最大并行任务调用数(默认:3)
|
||||
|
||||
如果 Agent 尝试调用超过限制的子 Agent,中间件会裁剪多余的调用。
|
||||
|
||||
## ACP Agent(外部 Agent)
|
||||
|
||||
除内置子 Agent 外,DeerFlow 还通过 **Agent Connect Protocol (ACP)** 支持委派给外部 Agent。ACP 允许 DeerFlow 调用作为独立进程运行的 Agent(包括用 ACP 适配器包装的第三方 CLI 工具)。
|
||||
|
||||
在 `config.yaml` 中配置 ACP Agent:
|
||||
|
||||
```yaml
|
||||
acp_agents:
|
||||
claude_code:
|
||||
command: npx
|
||||
args: ["-y", "@zed-industries/claude-agent-acp"]
|
||||
description: 用于实现、重构和调试的 Claude Code
|
||||
model: null
|
||||
|
||||
codex:
|
||||
command: npx
|
||||
args: ["-y", "@zed-industries/codex-acp"]
|
||||
description: 用于仓库任务和代码生成的 Codex CLI
|
||||
model: null
|
||||
```
|
||||
|
||||
Lead Agent 通过 `invoke_acp_agent` 内置工具调用 ACP Agent。
|
||||
|
||||
<Callout type="tip">
|
||||
ACP Agent 作为 DeerFlow 管理的子进程运行,通过 ACP 协议通信。标准 CLI 工具(如原始的 `claude` 或 `codex` 命令)默认不兼容 ACP——请使用上面列出的适配器包或兼容的 ACP 封装器。
|
||||
</Callout>
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="沙箱" href="/docs/harness/sandbox" />
|
||||
<Cards.Card title="MCP 集成" href="/docs/harness/mcp" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,205 @@
|
||||
import { Callout, Cards, Tabs } from "nextra/components";
|
||||
|
||||
# 工具
|
||||
|
||||
<Callout type="info" emoji="🔧">
|
||||
工具是 Lead Agent 可以采取的行动。DeerFlow 提供内置工具、社区集成、MCP 工具和技能工具——全部通过 <code>config.yaml</code> 控制。
|
||||
</Callout>
|
||||
|
||||
Lead Agent 是一个工具调用 Agent。工具是它与世界交互的方式:搜索网络、读写文件、运行命令、委派任务以及向用户呈现输出。
|
||||
|
||||
DeerFlow 将工具分为四类:
|
||||
|
||||
1. **内置工具** — 核心运行时能力,始终对 Agent 可用
|
||||
2. **社区工具** — 与外部搜索、抓取和图像服务的集成
|
||||
3. **MCP 工具** — 由外部 Model Context Protocol 服务器提供的工具
|
||||
4. **技能工具** — 与特定技能包捆绑的工具
|
||||
|
||||
## 内置工具
|
||||
|
||||
内置工具是 Harness 的一部分,无需配置即可使用。
|
||||
|
||||
### task
|
||||
|
||||
将子任务委派给子 Agent。当任务对单个推理线程来说太宽泛,或并行工作有利时,Lead Agent 使用此工具。
|
||||
|
||||
```
|
||||
task(agent="general-purpose", task="...", context="...")
|
||||
```
|
||||
|
||||
参见[子 Agent](/docs/harness/subagents)页面了解子 Agent 的配置方式。
|
||||
|
||||
---
|
||||
|
||||
### present_files
|
||||
|
||||
将输出文件作为产出物呈现给用户。Agent 在生成文件(报告、图表、代码等)后调用此工具,将其显示在对话中。
|
||||
|
||||
---
|
||||
|
||||
### view_image
|
||||
|
||||
读取图像文件并将其内容注入到模型的上下文中进行视觉分析。仅当活跃模型具有 `supports_vision: true` 时可用。
|
||||
|
||||
---
|
||||
|
||||
### clarification
|
||||
|
||||
在继续之前向用户提问。当模型认为没有足够信息来行动时,由 `ClarificationMiddleware` 触发。
|
||||
|
||||
---
|
||||
|
||||
### setup_agent
|
||||
|
||||
动态配置当前 Agent 会话。在设置新自定义 Agent 的引导流程中使用。
|
||||
|
||||
---
|
||||
|
||||
### invoke_acp_agent
|
||||
|
||||
使用 [Agent Connect Protocol (ACP)](https://agentconnectprotocol.org/) 调用外部 Agent。需要在 `config.yaml` 中配置 `acp_agents:`。参见[子 Agent](/docs/harness/subagents)页面了解 ACP 配置。
|
||||
|
||||
---
|
||||
|
||||
### tool_search
|
||||
|
||||
按名称或描述搜索工具,并按需将其加载到 Agent 上下文中。仅当 `config.yaml` 中 `tool_search.enabled: true` 时激活。当 MCP 或其他工具集暴露大量工具且你希望减少上下文使用时很有用。
|
||||
|
||||
## 沙箱文件工具
|
||||
|
||||
以下工具与沙箱文件系统交互,需要配置并激活沙箱。
|
||||
|
||||
| 工具 | 描述 |
|
||||
|---|---|
|
||||
| `ls` | 列出目录中的文件 |
|
||||
| `read_file` | 读取文件内容 |
|
||||
| `glob` | 查找匹配模式的文件 |
|
||||
| `grep` | 搜索文件内容 |
|
||||
| `write_file` | 向文件写入内容 |
|
||||
| `str_replace` | 替换文件中的字符串 |
|
||||
| `bash` | 执行 Shell 命令(需要 `allow_host_bash: true` 或容器沙箱) |
|
||||
|
||||
在 `config.yaml` 的 `tools:` 下配置:
|
||||
|
||||
```yaml
|
||||
tools:
|
||||
- use: deerflow.sandbox.tools:ls_tool
|
||||
- use: deerflow.sandbox.tools:read_file_tool
|
||||
- use: deerflow.sandbox.tools:glob_tool
|
||||
- use: deerflow.sandbox.tools:grep_tool
|
||||
- use: deerflow.sandbox.tools:write_file_tool
|
||||
- use: deerflow.sandbox.tools:str_replace_tool
|
||||
- use: deerflow.sandbox.tools:bash_tool
|
||||
```
|
||||
|
||||
## 社区工具
|
||||
|
||||
社区工具将 Agent 连接到外部服务。在 `config.yaml` 的 `tools:` 下使用 `use:` 字段指定实现来配置。
|
||||
|
||||
### 网络搜索
|
||||
|
||||
<Tabs items={["DuckDuckGo(默认)", "Tavily", "Exa", "Firecrawl"]}>
|
||||
<Tabs.Tab>
|
||||
```yaml
|
||||
tools:
|
||||
- use: deerflow.community.ddg_search.tools:web_search_tool
|
||||
```
|
||||
无需 API Key。默认配置,适合开发和通用用途。
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```yaml
|
||||
tools:
|
||||
- use: deerflow.community.tavily.tools:web_search_tool
|
||||
api_key: $TAVILY_API_KEY
|
||||
```
|
||||
高质量搜索,带结构化结果。需要 [Tavily](https://tavily.com) API Key。
|
||||
|
||||
安装:`cd backend && uv add 'deerflow-harness[tavily]'`
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```yaml
|
||||
tools:
|
||||
- use: deerflow.community.exa.tools:web_search_tool
|
||||
api_key: $EXA_API_KEY
|
||||
```
|
||||
带神经检索的语义搜索。需要 [Exa](https://exa.ai) API Key。
|
||||
|
||||
安装:`cd backend && uv add 'deerflow-harness[exa]'`
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```yaml
|
||||
tools:
|
||||
- use: deerflow.community.firecrawl.tools:web_search_tool
|
||||
api_key: $FIRECRAWL_API_KEY
|
||||
```
|
||||
Firecrawl 驱动的搜索和爬取。需要 [Firecrawl](https://firecrawl.dev) API Key。
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
|
||||
### 网页内容抓取
|
||||
|
||||
<Tabs items={["Jina AI(默认)", "Exa"]}>
|
||||
<Tabs.Tab>
|
||||
```yaml
|
||||
tools:
|
||||
- use: deerflow.community.jina_ai.tools:web_fetch_tool
|
||||
api_key: $JINA_API_KEY # 可选;匿名使用有速率限制
|
||||
```
|
||||
将网页转换为干净的 Markdown。无 API Key 也可使用,但有更严格的速率限制。
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```yaml
|
||||
tools:
|
||||
- use: deerflow.community.exa.tools:web_fetch_tool
|
||||
api_key: $EXA_API_KEY
|
||||
```
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
|
||||
### 图像搜索
|
||||
|
||||
```yaml
|
||||
tools:
|
||||
- use: deerflow.community.image_search.tools:image_search_tool
|
||||
```
|
||||
|
||||
## 工具组
|
||||
|
||||
工具组允许你将工具组织为命名集合,并限制自定义 Agent 可以访问哪些组:
|
||||
|
||||
```yaml
|
||||
tool_groups:
|
||||
- name: research
|
||||
tools:
|
||||
- web_search
|
||||
- web_fetch
|
||||
- image_search
|
||||
- name: coding
|
||||
tools:
|
||||
- bash
|
||||
- read_file
|
||||
- write_file
|
||||
- str_replace
|
||||
- glob
|
||||
- grep
|
||||
```
|
||||
|
||||
自定义 Agent 然后可以在其配置中按名称引用组,将其工具访问限制为仅相关集合。
|
||||
|
||||
## 工具搜索(延迟加载)
|
||||
|
||||
当有许多工具时(特别是来自多个 MCP 服务器),预先加载所有工具会增加上下文使用量并可能混淆模型。工具搜索功能解决了这个问题:
|
||||
|
||||
```yaml
|
||||
tool_search:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
启用后,工具不会直接列在模型上下文中。相反,它们在运行时通过 `tool_search` 内置工具按需发现,Agent 按名称或描述搜索,匹配的工具按需加载到上下文中。
|
||||
|
||||
当 MCP 服务器暴露数十个工具时特别有用。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="MCP 集成" href="/docs/harness/mcp" />
|
||||
<Cards.Card title="技能" href="/docs/harness/skills" />
|
||||
</Cards>
|
||||
@@ -1,6 +1,66 @@
|
||||
---
|
||||
title: 概览
|
||||
title: DeerFlow 文档
|
||||
description: 了解 DeerFlow,使用 Harness 构建,并部署应用。
|
||||
---
|
||||
|
||||
# 概览
|
||||
# DeerFlow 文档
|
||||
|
||||
DeerFlow 是一个用于构建和运行 Agent 系统的框架。它提供了一个运行时 Harness,可以将 Agent 与记忆、工具、技能、沙箱和子 Agent 组合在一起;同时还提供了一个应用层,将这些能力转化为可用的产品体验。
|
||||
|
||||
本文档围绕这两个部分组织:
|
||||
|
||||
- **DeerFlow Harness**:用于构建 Agent 系统的核心 SDK 和运行时层。
|
||||
- **DeerFlow 应用**:构建在 Harness 之上的参考应用,用于部署、运维和终端用户工作流。
|
||||
|
||||
如果你想了解 DeerFlow 的工作原理,从简介开始阅读。如果你想基于核心运行时进行开发,请查阅 Harness 文档。如果你想将 DeerFlow 作为应用部署和使用,请查阅应用文档。
|
||||
|
||||
## 从这里开始
|
||||
|
||||
### 如果你是 DeerFlow 新手
|
||||
|
||||
先从概念概述开始。
|
||||
|
||||
- [简介](/docs/introduction)
|
||||
- [为什么选择 DeerFlow](/docs/introduction/why-deerflow)
|
||||
- [Harness 与应用的区别](/docs/introduction/harness-vs-app)
|
||||
|
||||
### 如果你想基于 DeerFlow 进行开发
|
||||
|
||||
从 Harness 章节开始。这条路径适合想将 DeerFlow 功能集成到自己系统中,或基于 DeerFlow 运行时构建自定义 Agent 产品的团队。
|
||||
|
||||
- [DeerFlow Harness](/docs/harness)
|
||||
- [快速上手](/docs/harness/quick-start)
|
||||
- [配置](/docs/harness/configuration)
|
||||
- [自定义与扩展](/docs/harness/customization)
|
||||
|
||||
### 如果你想部署和使用 DeerFlow
|
||||
|
||||
从应用章节开始。这条路径适合想将 DeerFlow 作为完整应用运行,并了解如何配置、运维和实际使用的团队。
|
||||
|
||||
- [DeerFlow 应用](/docs/application)
|
||||
- [快速上手](/docs/application/quick-start)
|
||||
- [部署指南](/docs/application/deployment-guide)
|
||||
- [工作区使用](/docs/application/workspace-usage)
|
||||
|
||||
## 文档结构
|
||||
|
||||
### 简介
|
||||
|
||||
简介章节帮助你在深入实现细节之前建立正确的思维模型。
|
||||
|
||||
### DeerFlow Harness
|
||||
|
||||
Harness 章节是技术文档的核心,面向想要构建基于 DeerFlow 系统的开发者。
|
||||
|
||||
### DeerFlow 应用
|
||||
|
||||
应用章节面向想要将 DeerFlow 作为可用产品部署的团队。
|
||||
|
||||
### 教程
|
||||
|
||||
教程章节提供实践性的、面向任务的学习内容。
|
||||
|
||||
### 参考
|
||||
|
||||
参考章节提供详细的查阅资料,包括配置、运行时模式、API 和代码映射。
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { MetaRecord } from "nextra";
|
||||
|
||||
const meta: MetaRecord = {
|
||||
"why-deerflow": {
|
||||
title: "为什么选择 DeerFlow",
|
||||
},
|
||||
"core-concepts": {
|
||||
title: "核心概念",
|
||||
},
|
||||
"harness-vs-app": {
|
||||
title: "Harness 与应用",
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
@@ -0,0 +1,88 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# 核心概念
|
||||
|
||||
<Callout type="important" emoji="🧠">
|
||||
如果你将 DeerFlow 理解为一个长时序 Agent 的运行时,而不仅仅是聊天界面或工作流图,它将最易于理解。
|
||||
</Callout>
|
||||
|
||||
在深入了解 DeerFlow 之前,先建立一些贯穿整个系统的核心概念。这些概念解释了 DeerFlow 的优化目标以及其架构设计的原因。
|
||||
|
||||
## Harness
|
||||
|
||||
在 DeerFlow 中,**Harness** 是为 Agent 提供所需运行环境的运行时层,让 Agent 能够真正完成工作。
|
||||
|
||||
框架通常提供抽象和构建块。Harness 更进一步:它打包了一套有主张的运行时能力,让 Agent 无需每次重建相同基础设施,就能在真实环境中进行规划、行动、使用工具、管理文件和处理长时序任务。
|
||||
|
||||
在实践中,DeerFlow 的 Harness 包括:
|
||||
|
||||
- 工具访问
|
||||
- 技能加载
|
||||
- 沙箱执行
|
||||
- 记忆
|
||||
- 子 Agent 协调
|
||||
- 上下文管理
|
||||
|
||||
这就是为什么 DeerFlow 既不仅是一个模型封装器,也不仅是一个工作流图——它是一个 Agent 运行环境。
|
||||
|
||||
## 长时序 Agent
|
||||
|
||||
**长时序 Agent** 是一种在一系列动作中持续有效,而不仅产生单一答案的 Agent。
|
||||
|
||||
这类 Agent 可能需要:
|
||||
|
||||
1. 制定计划
|
||||
2. 反复决定下一步
|
||||
3. 多次调用工具
|
||||
4. 检查和修改文件
|
||||
5. 存储中间结果
|
||||
6. 最终返回可用的产出物
|
||||
|
||||
重点不只是时间长度,而是跨多个步骤的持续协调。
|
||||
|
||||
DeerFlow 专为这类工作设计。其架构假设有用的任务通常需要不止一次工具调用和不止一轮推理。
|
||||
|
||||
## 技能(Skill)
|
||||
|
||||
**技能**是一个面向任务的能力包,教会 Agent 如何完成某一类工作。
|
||||
|
||||
技能不仅仅是一个标签。它通常包括结构化指令、工作流程、最佳实践和支撑资源,可以在相关时加载。这使基础 Agent 保持通用性,同时只在需要时添加专业化行为。
|
||||
|
||||
在 DeerFlow 中,深度研究是一项技能。数据分析、内容生成、设计工作流和其他任务类型也可以表示为技能。
|
||||
|
||||
这是 DeerFlow 心智模型的重要组成部分:运行时保持通用,技能提供专业化。
|
||||
|
||||
## 沙箱(Sandbox)
|
||||
|
||||
**沙箱**是 Agent 进行文件和命令操作的隔离执行环境。
|
||||
|
||||
DeerFlow 不把 Agent 视为纯文本生成器,而是给它一个工作区,让它可以读取文件、写入输出、运行命令并生成产出物。这使系统在编码、分析和多步骤工作流中更加实用。
|
||||
|
||||
隔离性很重要,因为执行应该可控且可重现。沙箱让 DeerFlow 支持真实行动,而不仅仅是对话。
|
||||
|
||||
## 子 Agent(Subagent)
|
||||
|
||||
**子 Agent** 是处理委派子任务的专注执行者。
|
||||
|
||||
当一个任务对单个推理线程来说太宽泛时,DeerFlow 可以将工作拆分为较小的单元并分别运行。子 Agent 有助于并行探索、范围隔离执行,以及减轻主 Agent 的负担。
|
||||
|
||||
关键思路是隔离。子 Agent 不需要完整的对话历史或父上下文中的每一个细节——它只需要完成其分配工作所需的信息。
|
||||
|
||||
## 上下文工程(Context Engineering)
|
||||
|
||||
**上下文工程**是控制 Agent 在何时看到、记住和忽略什么内容的实践,以使其在长期任务中保持有效。
|
||||
|
||||
长时序任务会给上下文窗口带来压力。如果所有内容永远内联保存,Agent 会变得越来越慢、越来越嘈杂、越来越不可靠。DeerFlow 通过摘要压缩、为子 Agent 创建范围隔离的上下文、以及将文件系统作为外部工作记忆等技术来解决这一问题。
|
||||
|
||||
这是 DeerFlow 中最重要的思想之一。好的 Agent 行为不仅仅依靠更强大的模型——还需要在正确的时间给模型提供正确的工作集。
|
||||
|
||||
## 记忆(Memory)
|
||||
|
||||
**记忆**允许 Agent 在多个会话中保留有用信息。
|
||||
|
||||
DeerFlow 的记忆系统存储用户偏好、项目背景和 Agent 从对话中学到的持久性事实。这些信息在后续会话中注入到系统提示中,让 Agent 无需从零开始即可建立在过往上下文之上。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="Harness 与应用" href="/docs/introduction/harness-vs-app" />
|
||||
<Cards.Card title="设计理念" href="/docs/harness/design-principles" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# Harness 与应用
|
||||
|
||||
<Callout type="info" emoji="⚙️">
|
||||
DeerFlow 应用是构建在 DeerFlow Harness 之上的最佳实践 Super Agent 应用,而 DeerFlow Harness 是构建自己 Agent 系统的 Python SDK 和运行时基础。
|
||||
</Callout>
|
||||
|
||||
DeerFlow 有两个紧密相关但服务于不同目的的层次:
|
||||
|
||||
- **DeerFlow Harness** 是运行时基础层。
|
||||
- **DeerFlow 应用** 是构建在该基础之上的最佳实践应用。
|
||||
|
||||
理解这一区别,能让其余文档更易于阅读。
|
||||
|
||||
## Harness 是运行时层
|
||||
|
||||
**DeerFlow Harness** 是用于构建和运行长时序 Agent 的可复用系统。
|
||||
|
||||
它提供:长时序任务的规划和执行、工具调用和沙箱执行、技能加载和上下文注入、记忆和跨会话持久化、子 Agent 协调、以及完整的配置和扩展系统。
|
||||
|
||||
Harness 是 Python 库和运行时引擎。你可以将它导入到自己的应用中,或者直接使用 DeerFlow 应用,后者已经为你完成了所有集成工作。
|
||||
|
||||
## 应用是产品层
|
||||
|
||||
**DeerFlow 应用**是一个完整的、可部署的产品,它将 Harness 功能封装成可用的体验:
|
||||
|
||||
- 基于浏览器的对话工作区(Next.js 前端)
|
||||
- FastAPI Gateway,处理 API 操作
|
||||
- nginx 反向代理,统一所有服务
|
||||
- LangGraph 服务器,运行 DeerFlow Harness
|
||||
|
||||
应用是 Harness 所有功能的参考实现。它展示了如何将运行时能力组装成一个对最终用户和运维团队都易于使用的产品。
|
||||
|
||||
## 应该从哪里开始
|
||||
|
||||
### 我想将 DeerFlow 集成到自己的系统中
|
||||
|
||||
使用 **Harness**。将其作为 Python 库导入,使用 `DeerFlowClient` API 发送消息和流式传输响应,并通过 `config.yaml` 配置行为。
|
||||
|
||||
→ 从 [Harness 快速上手](/docs/harness/quick-start) 开始
|
||||
|
||||
### 我想运行 DeerFlow 作为对话工作区
|
||||
|
||||
使用**应用**。运行 `make dev` 或部署 Docker Compose 配置,然后通过浏览器访问。
|
||||
|
||||
→ 从 [应用快速上手](/docs/application/quick-start) 开始
|
||||
|
||||
### 我想了解架构原理
|
||||
|
||||
先阅读**简介**,然后是 Harness 的[设计理念](/docs/harness/design-principles)。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="Harness 快速上手" href="/docs/harness/quick-start" />
|
||||
<Cards.Card title="应用快速上手" href="/docs/application/quick-start" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
|
||||
# 为什么选择 DeerFlow
|
||||
|
||||
<Callout type="info" emoji="🦌">
|
||||
DeerFlow 起源于深度研究,但逐渐演化为一个通用的长时序 Agent 运行时——支持技能、记忆、工具和协作调度。
|
||||
</Callout>
|
||||
|
||||
DeerFlow 的诞生是因为现代 Agent 系统需要的不仅仅是一个聊天循环。一个真正有用的 Agent 必须能够进行长时序规划、将任务拆解为子任务、使用工具、操作文件、安全地运行代码,并在复杂任务中保持足够的上下文连贯性。DeerFlow 正是为提供这样的运行时基础而构建的。
|
||||
|
||||
## 从深度研究起步
|
||||
|
||||
DeerFlow 的第一个版本围绕一个具体目标设计:生成真正有深度的研究产出,而不是轻量级聊天机器人的概要总结。核心思路是让 AI 系统像研究团队一样工作:制定计划、收集来源、交叉验证发现,并输出有实际深度的结构化结果。
|
||||
|
||||
这个定位是有效的,但项目很快揭示了更重要的东西。团队不仅将 DeerFlow 用于研究——他们将其应用于数据分析、报告生成、内部自动化、运营工作流,以及其他同样需要多步骤执行的任务。
|
||||
|
||||
共同点是清晰的:有价值的部分不仅仅是研究工作流本身,而是其背后的运行时能力。
|
||||
|
||||
## 研究是第一个技能,而非整个系统
|
||||
|
||||
这种使用方式的转变带来了一个关键结论:深度研究应该被视为更广泛 Agent 运行时中的一项能力,而不是整个产品的定义。
|
||||
|
||||
因此,DeerFlow 从一个以单一研究模式为中心的项目演化为一个通用的长时序 Agent Harness。在这个模型中,研究仍然重要,但它成为众多技能中的一项,而非系统的固定形态。
|
||||
|
||||
这就是为什么 DeerFlow 被描述为 **Harness**,而不仅仅是框架或应用。
|
||||
|
||||
## 为什么 Harness 很重要
|
||||
|
||||
Harness 是一个带有主张的 Agent 运行时。它不只是暴露抽象接口。它打包了 Agent 在真实环境中做有用工作所需的基础设施——工具访问、技能加载、沙箱执行、记忆、子 Agent 协调和上下文管理。
|
||||
|
||||
这让开发者可以专注于他们试图解决的问题,而不是重复构建相同的基础设施层。
|
||||
|
||||
## DeerFlow 解决的问题
|
||||
|
||||
DeerFlow 专注于以下几个具体问题:
|
||||
|
||||
**长时序执行**:大多数有用的任务不能在单次推理中完成。DeerFlow 的架构假设工具调用、规划和多轮推理是正常情况,而非特例。
|
||||
|
||||
**上下文管理**:随着任务变长,上下文窗口压力成为主要挑战。DeerFlow 通过摘要压缩、范围隔离的子 Agent 上下文和文件系统作为外部记忆来主动管理这一问题。
|
||||
|
||||
**技能组合**:不同的工作类型需要不同的方法。DeerFlow 让技能成为可组合的能力包,而不是把所有内容硬编码到主 Agent 逻辑中。
|
||||
|
||||
**沙箱执行**:真实任务需要文件操作和命令执行。DeerFlow 提供一个隔离的工作区,让 Agent 可以安全地进行实际操作。
|
||||
|
||||
<Cards num={2}>
|
||||
<Cards.Card title="核心概念" href="/docs/introduction/core-concepts" />
|
||||
<Cards.Card title="Harness 与应用" href="/docs/introduction/harness-vs-app" />
|
||||
</Cards>
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { MetaRecord } from "nextra";
|
||||
|
||||
const meta: MetaRecord = {
|
||||
"concepts-glossary": {
|
||||
title: "概念词汇表",
|
||||
},
|
||||
"configuration-reference": {
|
||||
title: "配置参考",
|
||||
},
|
||||
"api-gateway-reference": {
|
||||
title: "API / Gateway 参考",
|
||||
},
|
||||
"runtime-flags-and-modes": {
|
||||
title: "运行时标志与模式",
|
||||
},
|
||||
"source-map": {
|
||||
title: "代码映射",
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# API / Gateway 参考
|
||||
|
||||
<Callout type="info">
|
||||
DeerFlow Gateway 是基于 FastAPI 构建的,提供交互式 API 文档,可通过 <code>http://localhost:8001/docs</code> 访问。
|
||||
</Callout>
|
||||
|
||||
## 基础 URL
|
||||
|
||||
```
|
||||
http://localhost:8001
|
||||
```
|
||||
|
||||
通过 nginx 代理:
|
||||
|
||||
```
|
||||
http://localhost:2026/api
|
||||
```
|
||||
|
||||
## 核心端点
|
||||
|
||||
### 系统
|
||||
|
||||
| 方法 | 路径 | 描述 |
|
||||
|---|---|---|
|
||||
| `GET` | `/health` | 服务健康检查 |
|
||||
| `GET` | `/api/models` | 获取已配置的模型列表 |
|
||||
|
||||
### Agent 管理
|
||||
|
||||
| 方法 | 路径 | 描述 |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/agents` | 列出所有 Agent |
|
||||
| `POST` | `/api/agents` | 创建自定义 Agent |
|
||||
| `GET` | `/api/agents/{name}` | 获取 Agent 配置 |
|
||||
| `PUT` | `/api/agents/{name}` | 更新 Agent 配置 |
|
||||
| `DELETE` | `/api/agents/{name}` | 删除 Agent |
|
||||
| `POST` | `/api/agents/check` | 检查/建议 Agent slug 唯一性 |
|
||||
|
||||
### 线程和记忆
|
||||
|
||||
| 方法 | 路径 | 描述 |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/threads` | 列出线程 |
|
||||
| `DELETE` | `/api/threads/{thread_id}` | 删除线程 |
|
||||
| `GET` | `/api/memory` | 获取全局记忆 |
|
||||
| `GET` | `/api/memory/{agent_name}` | 获取 Agent 特定记忆 |
|
||||
| `DELETE` | `/api/memory` | 清除全局记忆 |
|
||||
|
||||
### 扩展
|
||||
|
||||
| 方法 | 路径 | 描述 |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/extensions` | 列出所有扩展(MCP 服务器和技能) |
|
||||
| `POST` | `/api/extensions/mcp/{name}/enable` | 启用 MCP 服务器 |
|
||||
| `POST` | `/api/extensions/mcp/{name}/disable` | 禁用 MCP 服务器 |
|
||||
| `POST` | `/api/extensions/skills/{name}/enable` | 启用技能 |
|
||||
| `POST` | `/api/extensions/skills/{name}/disable` | 禁用技能 |
|
||||
|
||||
### 文件上传
|
||||
|
||||
| 方法 | 路径 | 描述 |
|
||||
|---|---|---|
|
||||
| `POST` | `/api/uploads/{thread_id}` | 上传文件到线程工作区 |
|
||||
| `GET` | `/api/uploads/{thread_id}/{filename}` | 获取上传的文件 |
|
||||
|
||||
完整的交互式 API 文档请访问 `http://localhost:8001/docs`(Swagger UI)。
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 概念词汇表
|
||||
|
||||
本词汇表定义了 DeerFlow 文档中使用的核心术语。
|
||||
|
||||
---
|
||||
|
||||
## Agent
|
||||
|
||||
在 DeerFlow 中,Agent 是接收用户消息、决定采取什么行动(工具调用或直接响应),并生成输出的主要处理单元。DeerFlow 使用 **Lead Agent** 和**子 Agent** 两级架构。
|
||||
|
||||
## Artifact(产出物)
|
||||
|
||||
Agent 生成的文件——报告、图表、代码或其他交付物。产出物通过 `present_files` 工具暴露,并持久化存储在线程的用户数据目录中。
|
||||
|
||||
## Checkpoint(检查点)
|
||||
|
||||
线程状态的持久化快照,在每次 Agent 轮次后保存。检查点允许服务器重启后恢复对话,并支持长时序任务的状态管理。
|
||||
|
||||
## Context Engineering(上下文工程)
|
||||
|
||||
通过控制 Agent 在每个步骤可见的内容(通过摘要压缩、子 Agent 上下文隔离和外部文件记忆)来保持 Agent 在长时序任务中有效的实践。
|
||||
|
||||
## Harness
|
||||
|
||||
带有主张的 Agent 运行时,打包了工具访问、技能加载、沙箱执行、记忆、子 Agent 协调和上下文管理——而不仅仅是暴露抽象接口。
|
||||
|
||||
## Lead Agent
|
||||
|
||||
每个 DeerFlow 线程中的主要执行者,负责规划、工具调用和响应生成。基于 LangGraph + LangChain Agent 构建,由中间件链增强。
|
||||
|
||||
## Long-horizon Agent(长时序 Agent)
|
||||
|
||||
在一系列动作中保持有效的 Agent——进行规划、多次调用工具、管理中间文件,并生成最终产出物——而不是只产生单一答案。
|
||||
|
||||
## Memory(记忆)
|
||||
|
||||
跨多个独立对话会话持久化的结构化事实和用户上下文存储,在后续会话中注入到 Agent 的系统提示中。
|
||||
|
||||
## Middleware(中间件)
|
||||
|
||||
包裹每次 LLM 调用的插件,可以在模型调用前后读取和修改 Agent 状态。DeerFlow 使用中间件实现记忆、摘要压缩、标题生成等跨领域行为。
|
||||
|
||||
## MCP(Model Context Protocol)
|
||||
|
||||
连接语言模型与外部工具和数据源的开放标准。DeerFlow 的 MCP 集成允许连接任何兼容的工具服务器。
|
||||
|
||||
## Sandbox(沙箱)
|
||||
|
||||
Agent 进行文件和命令操作的隔离执行环境。DeerFlow 支持本地(`LocalSandboxProvider`)和基于容器(`AioSandboxProvider`)两种沙箱模式。
|
||||
|
||||
## Skill(技能)
|
||||
|
||||
面向任务的能力包,包含结构化指令、工作流程和最佳实践,按需加载到 Agent 上下文中。技能提供专业化而不污染通用 Agent 上下文。
|
||||
|
||||
## Subagent(子 Agent)
|
||||
|
||||
接受委派子任务的专注执行者,以隔离上下文运行,仅接收完成其分配任务所需的信息。
|
||||
|
||||
## Thread(线程)
|
||||
|
||||
对话及其所有相关状态——消息历史、产出物、待办列表和检查点数据——的完整封装。
|
||||
|
||||
## ThreadState
|
||||
|
||||
DeerFlow 中 LangGraph 管理的状态对象,包含 `messages`、`artifacts`、`todo_list` 和运行时元数据。
|
||||
@@ -0,0 +1,122 @@
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 配置参考
|
||||
|
||||
本页面提供 `config.yaml` 中所有顶层字段的完整参考。
|
||||
|
||||
<Callout type="info">
|
||||
查看仓库根目录中的 <code>config.example.yaml</code> 获取带注释的完整配置示例。
|
||||
</Callout>
|
||||
|
||||
## 顶层字段
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `config_version` | `int` | 配置 schema 版本(当前:6) |
|
||||
| `log_level` | `str` | 日志级别:`debug`/`info`/`warning`/`error` |
|
||||
| `models` | `list` | 可用的 LLM 模型配置 |
|
||||
| `image_generate_model` | `str \| list` | 图像生成使用的模型名称 |
|
||||
| `token_usage` | `object` | Token 使用追踪配置 |
|
||||
| `tools` | `list` | 可用工具配置 |
|
||||
| `tool_groups` | `list` | 工具的命名分组 |
|
||||
| `tool_search` | `object` | 延迟工具加载配置 |
|
||||
| `sandbox` | `object` | 沙箱提供者配置 |
|
||||
| `skills` | `object` | 技能目录和容器路径 |
|
||||
| `skill_evolution` | `object` | Agent 管理的技能创建 |
|
||||
| `subagents` | `object` | 子 Agent 超时和最大轮次 |
|
||||
| `acp_agents` | `dict` | 外部 ACP Agent 配置 |
|
||||
| `memory` | `object` | 跨会话记忆存储 |
|
||||
| `summarization` | `object` | 对话摘要压缩 |
|
||||
| `title` | `object` | 自动线程标题生成 |
|
||||
| `checkpointer` | `object` | 线程状态持久化 |
|
||||
| `guardrails` | `object` | 工具调用授权 |
|
||||
| `uploads` | `object` | 文件上传配置 |
|
||||
| `channels` | `list` | IM 频道集成 |
|
||||
|
||||
## models
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: gpt-4o # 模型标识符(在请求中引用)
|
||||
use: langchain_openai:ChatOpenAI # Python 类路径
|
||||
model: gpt-4o # 传给 LLM 的模型名称
|
||||
api_key: $OPENAI_API_KEY # API 密钥(支持环境变量)
|
||||
base_url: null # 可选:自定义端点
|
||||
request_timeout: 600.0 # 请求超时(秒)
|
||||
max_retries: 2 # 重试次数
|
||||
supports_vision: true # 是否启用视觉功能
|
||||
thinking_enabled: false # 是否启用扩展思考
|
||||
# 任何其他字段都会传递给模型构造函数
|
||||
```
|
||||
|
||||
## sandbox
|
||||
|
||||
```yaml
|
||||
sandbox:
|
||||
# 本地(默认,无容器隔离)
|
||||
use: deerflow.sandbox.local:LocalSandboxProvider
|
||||
allow_host_bash: false
|
||||
bash_output_max_chars: 20000
|
||||
read_file_output_max_chars: 50000
|
||||
ls_output_max_chars: 20000
|
||||
|
||||
# 基于容器
|
||||
# use: deerflow.community.aio_sandbox:AioSandboxProvider
|
||||
# image: enterprise-public-cn-beijing.cr.volces.com/vefaas-public/all-in-one-sandbox:latest
|
||||
# replicas: 3
|
||||
# idle_timeout: 600
|
||||
```
|
||||
|
||||
## memory
|
||||
|
||||
```yaml
|
||||
memory:
|
||||
enabled: true
|
||||
storage_path: memory.json
|
||||
debounce_seconds: 30
|
||||
max_facts: 100
|
||||
fact_confidence_threshold: 0.7
|
||||
injection_enabled: true
|
||||
max_injection_tokens: 2000
|
||||
model_name: null
|
||||
```
|
||||
|
||||
## summarization
|
||||
|
||||
```yaml
|
||||
summarization:
|
||||
enabled: true
|
||||
model_name: null
|
||||
trigger:
|
||||
- type: tokens
|
||||
value: 15564
|
||||
keep:
|
||||
type: messages
|
||||
value: 10
|
||||
trim_tokens_to_summarize: 15564
|
||||
summary_prompt: null
|
||||
```
|
||||
|
||||
## checkpointer
|
||||
|
||||
```yaml
|
||||
checkpointer:
|
||||
type: sqlite # sqlite | redis | postgres
|
||||
connection_string: .deer-flow/checkpoints.db
|
||||
```
|
||||
|
||||
## subagents
|
||||
|
||||
```yaml
|
||||
subagents:
|
||||
timeout_seconds: 900
|
||||
agents:
|
||||
general-purpose:
|
||||
timeout_seconds: 1800
|
||||
max_turns: 160
|
||||
bash:
|
||||
timeout_seconds: 300
|
||||
max_turns: 80
|
||||
```
|
||||
|
||||
参见各功能的文档页面了解所有字段的详细说明。
|
||||
@@ -0,0 +1,36 @@
|
||||
# 运行时标志与模式
|
||||
|
||||
本页面记录影响 DeerFlow Harness 和 Agent 运行时行为的运行时标志和模式。
|
||||
|
||||
## 每次请求的可配置选项
|
||||
|
||||
这些选项通过 `config.configurable` 字典传递(用于程序化使用)或在 Web UI 中选择(用于应用使用):
|
||||
|
||||
| 标志 | 类型 | 默认值 | 描述 |
|
||||
|---|---|---|---|
|
||||
| `model_name` | `str \| None` | 配置的第一个模型 | 请求使用的模型 |
|
||||
| `agent_name` | `str \| None` | `None` | 加载自定义 Agent 配置 |
|
||||
| `thinking_enabled` | `bool` | `True` | 启用扩展思考(模型必须支持) |
|
||||
| `reasoning_effort` | `str \| None` | `None` | 推理努力程度(模型特定) |
|
||||
| `is_plan_mode` | `bool` | `False` | 启用 TodoList 中间件 |
|
||||
| `subagent_enabled` | `bool` | `False` | 允许子 Agent 委派 |
|
||||
| `max_concurrent_subagents` | `int` | `3` | 最大并行子 Agent 调用数 |
|
||||
|
||||
## 环境变量
|
||||
|
||||
| 变量 | 默认值 | 描述 |
|
||||
|---|---|---|
|
||||
| `DEER_FLOW_CONFIG_PATH` | 自动发现 | `config.yaml` 的绝对路径 |
|
||||
| `LOG_LEVEL` | `info` | 日志级别覆盖 |
|
||||
| `DEER_FLOW_ROOT` | 仓库根目录 | Docker 挂载的基础路径 |
|
||||
| `BETTER_AUTH_SECRET` | — | 前端会话密钥(生产必须设置) |
|
||||
| `BETTER_AUTH_URL` | — | 公开 URL(用于回调和 CORS) |
|
||||
|
||||
## 模型能力标志
|
||||
|
||||
在 `config.yaml` 中的模型配置里设置:
|
||||
|
||||
| 标志 | 类型 | 描述 |
|
||||
|---|---|---|
|
||||
| `supports_vision` | `bool` | 模型接受图像输入 |
|
||||
| `thinking_enabled` | `bool` | 模型支持扩展思考模式 |
|
||||
@@ -0,0 +1,88 @@
|
||||
# 代码映射
|
||||
|
||||
本页面将 DeerFlow 的核心概念映射到其在代码库中的实现位置,帮助你快速定位特定功能的代码。
|
||||
|
||||
## 后端核心路径
|
||||
|
||||
```
|
||||
backend/
|
||||
├── app/
|
||||
│ └── gateway/ # FastAPI Gateway API
|
||||
│ ├── routers/
|
||||
│ │ ├── agents.py # 自定义 Agent CRUD
|
||||
│ │ ├── extensions.py # MCP/技能启用禁用
|
||||
│ │ ├── memory.py # 记忆读取/清除
|
||||
│ │ ├── threads.py # 线程管理
|
||||
│ │ └── uploads.py # 文件上传
|
||||
│ └── main.py # FastAPI 应用入口
|
||||
│
|
||||
└── packages/harness/deerflow/
|
||||
├── agents/
|
||||
│ ├── lead_agent/
|
||||
│ │ ├── agent.py # make_lead_agent() 工厂
|
||||
│ │ └── prompt.py # 系统提示模板
|
||||
│ ├── middlewares/ # 所有中间件实现
|
||||
│ ├── memory/
|
||||
│ │ ├── middleware.py # MemoryMiddleware
|
||||
│ │ └── storage.py # 记忆文件存储
|
||||
│ └── thread_state.py # ThreadState 数据类
|
||||
│
|
||||
├── config/
|
||||
│ ├── app_config.py # AppConfig(顶层配置)
|
||||
│ ├── model_config.py # ModelConfig
|
||||
│ ├── paths.py # 路径解析工具
|
||||
│ └── *.py # 各模块配置类
|
||||
│
|
||||
├── mcp/
|
||||
│ ├── cache.py # 基于 mtime 的工具缓存
|
||||
│ └── oauth.py # MCP OAuth 支持
|
||||
│
|
||||
├── models/
|
||||
│ └── factory.py # create_chat_model() LLM 工厂
|
||||
│
|
||||
├── sandbox/
|
||||
│ ├── local/ # LocalSandboxProvider
|
||||
│ └── sandbox.py # Sandbox 基类
|
||||
│
|
||||
├── skills/
|
||||
│ ├── loader.py # load_skills()(热重载)
|
||||
│ ├── parser.py # SKILL.md 解析
|
||||
│ ├── installer.py # 依赖安装
|
||||
│ └── manager.py # 技能生命周期
|
||||
│
|
||||
├── subagents/
|
||||
│ └── registry.py # 子 Agent 查找与配置覆盖
|
||||
│
|
||||
└── tools/
|
||||
└── builtins/ # 内置工具实现
|
||||
```
|
||||
|
||||
## 前端核心路径
|
||||
|
||||
```
|
||||
frontend/src/
|
||||
├── app/ # Next.js 路由
|
||||
├── components/
|
||||
│ └── workspace/ # 工作区 UI 组件
|
||||
├── core/
|
||||
│ ├── agents/ # Agent 类型和 API 客户端
|
||||
│ ├── messages/ # 消息类型和工具调用处理
|
||||
│ └── threads/ # 线程状态管理
|
||||
└── content/ # 文档内容(MDX)
|
||||
├── en/ # 英文文档
|
||||
└── zh/ # 中文文档
|
||||
```
|
||||
|
||||
## 关键文件快速索引
|
||||
|
||||
| 目标 | 文件 |
|
||||
|---|---|
|
||||
| Lead Agent 创建 | `agents/lead_agent/agent.py` |
|
||||
| 系统提示模板 | `agents/lead_agent/prompt.py` |
|
||||
| 所有中间件 | `agents/middlewares/` |
|
||||
| 配置加载 | `config/app_config.py` |
|
||||
| 模型工厂 | `models/factory.py` |
|
||||
| 技能加载(热重载) | `skills/loader.py` |
|
||||
| MCP 工具缓存 | `mcp/cache.py` |
|
||||
| 文件上传处理 | `uploads/manager.py` |
|
||||
| Gateway 主路由器 | `app/gateway/main.py` |
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { MetaRecord } from "nextra";
|
||||
|
||||
const meta: MetaRecord = {
|
||||
"first-conversation": {
|
||||
title: "第一次对话",
|
||||
},
|
||||
"create-your-first-harness": {
|
||||
title: "创建你的第一个 Harness",
|
||||
},
|
||||
"use-tools-and-skills": {
|
||||
title: "使用工具和技能",
|
||||
},
|
||||
"work-with-memory": {
|
||||
title: "使用记忆系统",
|
||||
},
|
||||
"deploy-your-own-deerflow": {
|
||||
title: "部署你的 DeerFlow",
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
@@ -0,0 +1,83 @@
|
||||
# 创建你的第一个 Harness
|
||||
|
||||
本教程介绍如何以编程方式使用 DeerFlow Harness Python SDK——直接在你的 Python 代码中导入和使用 DeerFlow,而不是通过 Web 界面。
|
||||
|
||||
## 前置条件
|
||||
|
||||
- Python 3.12+
|
||||
- 已安装 `uv`
|
||||
- 已克隆 DeerFlow 仓库
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
cd deer-flow/backend
|
||||
uv sync
|
||||
```
|
||||
|
||||
## 创建配置
|
||||
|
||||
创建一个最小的 `config.yaml`:
|
||||
|
||||
```yaml
|
||||
config_version: 6
|
||||
|
||||
models:
|
||||
- name: gpt-4o
|
||||
use: langchain_openai:ChatOpenAI
|
||||
model: gpt-4o
|
||||
api_key: $OPENAI_API_KEY
|
||||
|
||||
sandbox:
|
||||
use: deerflow.sandbox.local:LocalSandboxProvider
|
||||
|
||||
tools:
|
||||
- use: deerflow.community.ddg_search.tools:web_search_tool
|
||||
- use: deerflow.sandbox.tools:read_file_tool
|
||||
- use: deerflow.sandbox.tools:write_file_tool
|
||||
```
|
||||
|
||||
## 编写代码
|
||||
|
||||
创建 `my_agent.py`:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import os
|
||||
from deerflow.client import DeerFlowClient
|
||||
from deerflow.config import load_config
|
||||
|
||||
# 设置 API Key
|
||||
os.environ["OPENAI_API_KEY"] = "sk-..."
|
||||
|
||||
# 加载配置
|
||||
load_config()
|
||||
|
||||
client = DeerFlowClient()
|
||||
|
||||
async def main():
|
||||
async for event in client.astream(
|
||||
thread_id="my-first-thread",
|
||||
message="用 Python 写一个斐波那契数列函数,包含文档字符串",
|
||||
config={
|
||||
"configurable": {
|
||||
"model_name": "gpt-4o",
|
||||
}
|
||||
},
|
||||
):
|
||||
print(event)
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
## 运行
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
uv run python my_agent.py
|
||||
```
|
||||
|
||||
## 下一步
|
||||
|
||||
- [使用工具和技能](/docs/tutorials/use-tools-and-skills)
|
||||
- [快速上手](/docs/harness/quick-start)
|
||||
@@ -0,0 +1,67 @@
|
||||
# 部署你的 DeerFlow
|
||||
|
||||
本教程引导你将 DeerFlow 部署到生产环境,使用 Docker Compose 进行多用户访问。
|
||||
|
||||
## 前置条件
|
||||
|
||||
- 已安装 Docker 和 Docker Compose
|
||||
- 服务器或 VM(Linux 推荐)
|
||||
- LLM API Key
|
||||
|
||||
## 步骤
|
||||
|
||||
### 1. 克隆仓库
|
||||
|
||||
```bash
|
||||
git clone https://github.com/bytedance/deer-flow.git
|
||||
cd deer-flow
|
||||
```
|
||||
|
||||
### 2. 创建配置文件
|
||||
|
||||
```bash
|
||||
cp config.example.yaml config.yaml
|
||||
```
|
||||
|
||||
编辑 `config.yaml` 添加你的模型配置。
|
||||
|
||||
### 3. 创建环境变量文件
|
||||
|
||||
```bash
|
||||
cat > .env << EOF
|
||||
OPENAI_API_KEY=sk-your-key-here
|
||||
DEER_FLOW_ROOT=$(pwd)
|
||||
BETTER_AUTH_SECRET=$(openssl rand -base64 32)
|
||||
BETTER_AUTH_URL=https://your-domain.com
|
||||
EOF
|
||||
```
|
||||
|
||||
### 4. 启动服务
|
||||
|
||||
```bash
|
||||
docker compose -f docker/docker-compose-dev.yaml up -d
|
||||
```
|
||||
|
||||
### 5. 验证部署
|
||||
|
||||
```bash
|
||||
# 检查所有服务健康状态
|
||||
curl http://localhost:2026/api/models
|
||||
|
||||
# 查看服务日志
|
||||
docker compose -f docker/docker-compose-dev.yaml logs -f
|
||||
```
|
||||
|
||||
访问 `http://your-server:2026` 开始使用。
|
||||
|
||||
## 生产注意事项
|
||||
|
||||
- 为 nginx 配置 HTTPS/TLS 证书
|
||||
- 将 `BETTER_AUTH_SECRET` 设置为强随机字符串
|
||||
- 配置防火墙只允许必要端口
|
||||
- 定期备份 `backend/.deer-flow/` 目录
|
||||
|
||||
## 下一步
|
||||
|
||||
- [部署指南(完整版)](/docs/application/deployment-guide)
|
||||
- [运维与排障](/docs/application/operations-and-troubleshooting)
|
||||
@@ -0,0 +1,43 @@
|
||||
# 第一次对话
|
||||
|
||||
本教程引导你在 DeerFlow 中完成第一次完整的 Agent 对话,从启动应用到与 Agent 进行实质性任务交互。
|
||||
|
||||
## 前置条件
|
||||
|
||||
- DeerFlow 应用已运行(参见[快速上手](/docs/application/quick-start))
|
||||
- 至少在 `config.yaml` 中配置了一个模型
|
||||
|
||||
## 步骤
|
||||
|
||||
### 1. 打开工作区
|
||||
|
||||
在浏览器中访问 [http://localhost:2026](http://localhost:2026),你将看到对话工作区。
|
||||
|
||||
### 2. 发送第一条消息
|
||||
|
||||
在输入框中输入问题,例如:
|
||||
|
||||
```
|
||||
研究 2024 年三大最受欢迎的开源大语言模型框架,并对比它们的优缺点。
|
||||
```
|
||||
|
||||
按回车发送。
|
||||
|
||||
### 3. 观察 Agent 的工作过程
|
||||
|
||||
你将看到 Agent 进入工作状态:
|
||||
- 展开**思考步骤**查看它调用了哪些工具
|
||||
- 观察网络搜索结果的流入
|
||||
- 等待最终报告生成
|
||||
|
||||
### 4. 与结果互动
|
||||
|
||||
报告生成后,你可以:
|
||||
- 要求对某部分进行详细说明
|
||||
- 要求将报告导出为文件(Agent 会使用 `present_files` 工具)
|
||||
- 要求基于研究结果创建图表
|
||||
|
||||
## 下一步
|
||||
|
||||
- [使用工具和技能](/docs/tutorials/use-tools-and-skills)
|
||||
- [工作区使用](/docs/application/workspace-usage)
|
||||
@@ -0,0 +1,47 @@
|
||||
# 使用工具和技能
|
||||
|
||||
本教程介绍如何在 DeerFlow 中配置和使用工具(Tools)与技能(Skills),让 Agent 能够访问搜索、文件操作和特定领域能力。
|
||||
|
||||
## 配置工具
|
||||
|
||||
在 `config.yaml` 中添加工具:
|
||||
|
||||
```yaml
|
||||
tools:
|
||||
# 网络搜索
|
||||
- use: deerflow.community.ddg_search.tools:web_search_tool
|
||||
|
||||
# 网页内容抓取
|
||||
- use: deerflow.community.jina_ai.tools:web_fetch_tool
|
||||
|
||||
# 沙箱文件操作
|
||||
- use: deerflow.sandbox.tools:ls_tool
|
||||
- use: deerflow.sandbox.tools:read_file_tool
|
||||
- use: deerflow.sandbox.tools:write_file_tool
|
||||
- use: deerflow.sandbox.tools:bash_tool
|
||||
```
|
||||
|
||||
## 启用技能
|
||||
|
||||
通过 DeerFlow 应用界面的技能面板启用技能,或直接编辑 `extensions_config.json`。
|
||||
|
||||
示例:启用深度研究技能
|
||||
|
||||
1. 打开 DeerFlow 应用
|
||||
2. 点击侧边栏中的扩展/技能图标
|
||||
3. 找到 `deep-research`,切换为启用
|
||||
|
||||
## 使用技能进行研究
|
||||
|
||||
启用 `deep-research` 技能后,在对话中选择该技能,然后发送研究请求:
|
||||
|
||||
```
|
||||
对量子计算的最新进展进行深度研究,重点关注实用化应用前景
|
||||
```
|
||||
|
||||
Agent 将执行多步骤研究工作流,包括搜索、信息汇总和报告生成。
|
||||
|
||||
## 下一步
|
||||
|
||||
- [使用记忆系统](/docs/tutorials/work-with-memory)
|
||||
- [技能文档](/docs/harness/skills)
|
||||
@@ -0,0 +1,52 @@
|
||||
# 使用记忆系统
|
||||
|
||||
本教程介绍如何在 DeerFlow 中启用和使用记忆系统,让 Agent 在多次会话中记住关于你的重要信息。
|
||||
|
||||
## 启用记忆
|
||||
|
||||
在 `config.yaml` 中启用记忆:
|
||||
|
||||
```yaml
|
||||
memory:
|
||||
enabled: true
|
||||
injection_enabled: true
|
||||
max_injection_tokens: 2000
|
||||
debounce_seconds: 30
|
||||
```
|
||||
|
||||
## 记忆的工作方式
|
||||
|
||||
记忆通过 `MemoryMiddleware` 自动工作:
|
||||
|
||||
1. **第一次对话**:告诉 Agent 关于你的偏好、项目或背景。
|
||||
2. **自动学习**:Agent 在后台提取并保存重要事实。
|
||||
3. **后续对话**:记忆事实自动注入到系统提示中,Agent 无需你重新解释背景。
|
||||
|
||||
## 示例
|
||||
|
||||
**第一次对话**:
|
||||
```
|
||||
我是一名 Python 后端开发者,主要使用 FastAPI 和 PostgreSQL。
|
||||
我的团队遵循 PEP 8 代码规范,偏好类型注解。
|
||||
请记住这些信息,在以后的代码建议中遵循这些规范。
|
||||
```
|
||||
|
||||
**后续对话**(无需重复背景):
|
||||
```
|
||||
帮我写一个用户认证模块
|
||||
```
|
||||
|
||||
Agent 会自动生成符合 FastAPI 风格、带类型注解的代码。
|
||||
|
||||
## 查看记忆
|
||||
|
||||
记忆存储在 `backend/.deer-flow/memory.json`,你可以直接查看和编辑:
|
||||
|
||||
```bash
|
||||
cat backend/.deer-flow/memory.json
|
||||
```
|
||||
|
||||
## 下一步
|
||||
|
||||
- [部署你的 DeerFlow](/docs/tutorials/deploy-your-own-deerflow)
|
||||
- [记忆系统文档](/docs/harness/memory)
|
||||
Reference in New Issue
Block a user