DeepAgent 项目分析
📁 项目路径:eino-examples/adk/multiagent/deep/
🎯 核心模式:Plan-Execute(计划-执行) 多智能体编排
一、项目概览
adk/multiagent/deep/ 是一个基于 Eino 框架 deep.New() 预构建 Agent 的多智能体 Excel/文件处理系统。它演示了 Plan-Execute(计划-执行) 模式:
1
| 主 Agent 制定分步计划 → 将每一步委派给专业化的子 Agent 执行
|
🔗 与参考文档 ch04 的关系
参考文档 ch04_tool_backend_filesystem.md |
本项目 adk/multiagent/deep/ |
deep.New() 最简用法 |
deep.New() 高级用法 |
仅配置 Backend + StreamingShell |
手动构建自定义 Tools 和 SubAgents |
| Agent 自动获得文件系统能力 |
展示多智能体编排能力 |
| 适合快速上手 |
适合生产级复杂任务 |
二、目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| adk/multiagent/deep/ ├── main.go # 入口:创建 DeepAgent + Runner,执行查询 ├── operator.go # LocalOperator:文件系统 & 命令执行的本地实现 ├── agents/ │ ├── code_agent.go # 子Agent:代码执行(Python/Bash) │ └── web_search.go # 子Agent:网络搜索(DuckDuckGo) ├── generic/ │ ├── plan.go # Plan / Step 数据结构 + create_plan 工具定义 │ ├── full_plan.go # FullPlan:带状态追踪的完整计划 │ ├── submit_result.go # SubmitResult 数据结构 + 目录遍历 │ └── file_preview.go # Excel 文件预览(解析 xlsx 的表头/内容/合并单元格) ├── tools/ │ ├── wrap.go # 工具包装器:请求预处理 + 响应后处理 │ ├── bash.go # bash 工具:执行 shell 命令 │ ├── edit.go # edit_file 工具:创建/覆盖写文件 │ ├── read.go # read_file 工具:按行读取文件内容 │ ├── tree.go # tree 工具:目录树结构查看 │ ├── python_runner.go # python_runner 工具:写 Python 代码并执行 │ ├── read_image.go # image_reader 工具:通过视觉模型分析图片 │ ├── submit_result.go # submit_result 工具:提交最终执行结果 │ └── option.go # 工具选项(operator 注入) ├── params/ │ ├── consts.go # Context 参数键名常量 │ └── params.go # 基于 sync.Map 的线程安全上下文参数管理 ├── utils/ │ ├── model.go # ChatModel 工厂(支持 ARK / OpenAI) │ └── utils.go # 通用工具函数(JSON修复、格式化等) └── playground/ ├── input/.gitkeep # 输入文件目录 └── test_data/ # 测试数据 ├── questions.csv ├── 推荐小说.txt └── 模拟出题.csv
|
三、三层架构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| ┌──────────────────────────────────────────────────────────────┐ │ Layer 1: 编排层 — DeepAgent (deep.New) │ │ 职责:制定计划 (create_plan) → 逐步委派子 Agent → 提交结果 │ │ 工具:read_file, tree, submit_result, create_plan │ ├──────────────────────────────────────────────────────────────┤ │ Layer 2: 子 Agent 层 │ │ ┌─────────────────────┐ ┌──────────────────────┐ │ │ │ CodeAgent │ │ WebSearchAgent │ │ │ │ • bash │ │ • duckduckgo_search │ │ │ │ • tree │ │ MaxIterations: 10 │ │ │ │ • edit_file │ └──────────────────────┘ │ │ │ • read_file │ │ │ │ • python_runner │ │ │ │ MaxIterations: 1000 │ │ │ └─────────────────────┘ │ ├──────────────────────────────────────────────────────────────┤ │ Layer 3: 基础设施层 │ │ LocalOperator (commandline.Operator 接口) │ │ • ReadFile / WriteFile / RunCommand │ │ params (sync.Map 上下文参数) │ │ utils (JSON修复、模型创建、格式化) │ └──────────────────────────────────────────────────────────────┘
|
四、核心执行流程
🎯 示例查询
1
| "请帮我将 questions.csv 表格中的第一列提取到一个新的 csv 中"
|
🔄 执行流程图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| 用户查询 │ ▼ ┌─ main.go ─────────────────────────────────────────────┐ │ 1. 生成 UUID 作为 TaskID │ │ 2. 创建工作目录 playground/{UUID}/ │ │ 3. 复制输入文件到工作目录 │ │ 4. PreviewPath() 预览 Excel 文件结构 │ │ 5. 初始化 Context 参数(文件路径、工作目录、预览信息) │ │ 6. 创建 Runner 并执行 │ └────────────────────────┬──────────────────────────────┘ │ ▼ ┌─ DeepAgent (Plan-Execute) ────────────────────────────┐ │ ① 分析任务 → 调用 create_plan 生成分步计划 │ │ Plan: [ │ │ {index:1, desc:"读取CSV结构"}, │ │ {index:2, desc:"编写Python提取第一列"}, │ │ {index:3, desc:"执行并验证"}, │ │ {index:4, desc:"提交结果"} │ │ ] │ │ │ │ ② 逐步执行: │ │ Step 1 → 委派 CodeAgent → read_file 读取 CSV │ │ Step 2 → 委派 CodeAgent → python_runner 执行提取 │ │ Step 3 → 委派 CodeAgent → read_file 验证结果 │ │ Step 4 → 调用 submit_result 提交最终结果 │ │ │ │ ③ 输出产物: │ │ • final_report.json (执行结果元数据) │ │ • plan.md (带状态的计划清单) │ │ • 生成的 CSV 文件 │ └────────────────────────────────────────────────────────┘
|
五、关键组件详解
5.1 DeepAgent 创建(main.go:153-194)
1 2 3 4 5 6 7 8 9 10 11 12 13
| deepAgent, err := deep.New(ctx, &deep.Config{ Name: "ExcelAgent", Description: "an agent for excel task", ChatModel: cm, SubAgents: []adk.Agent{ca, wa}, ToolsConfig: adk.ToolsConfig{ Tools: []tool.BaseTool{ tools.NewWrapTool(readFile, nil, nil), tools.NewWrapTool(tree, nil, nil), }, }, MaxIteration: 100, })
|
🎨 设计要点:
| 设计决策 |
目的 |
主 Agent 只配备 read_file 和 tree |
只读权限,仅用于理解文件结构 |
| 写操作和代码执行委派给 CodeAgent |
职责隔离,降低主 Agent 复杂度 |
MaxIteration: 100 |
控制最大循环次数,防止无限执行 |
5.2 CodeAgent(agents/code_agent.go)
1 2 3 4 5 6 7 8 9 10 11 12 13
| adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ Name: "CodeAgent", Description: "specialized in handling Excel files via Python code...", Model: cm, Tools: []tool.BaseTool{ bash, tree, edit_file, read_file, python_runner, }, MaxIterations: 1000, })
|
🔑 关键设计:
- ✅ 通过
GenModelInput 注入工作目录和当前时间到 Prompt
- ✅ 指令明确要求使用
pandas、matplotlib、openpyxl
- ✅ 所有工具都经过
WrapTool 包装,添加了 JSON 修复预处理
5.3 WebSearchAgent(agents/web_search.go)
1 2 3 4 5 6 7
| adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ Name: "WebSearchAgent", Description: "utilizes ReAct model... using web search tools", Model: cm, Tools: []tool.BaseTool{duckduckgo.NewTextSearchTool(...)}, MaxIterations: 10, })
|
💡 最简单的子 Agent,仅用于信息检索场景。
1 2 3 4 5 6 7
| 请求 ──→ [预处理链] ──→ 实际工具执行 ──→ [后处理链] ──→ 响应 │ │ ├─ ToolRequestRepairJSON ├─ FilePostProcess │ (修复LLM生成的损坏JSON) │ (格式化文件变更/stdout/stderr) │ │ └─ 清除 <|FunctionCallEnd|> └─ EditFilePostProcess 等模型格式残留 (简化为 "success" 消息)
|
❓ 为什么需要 JSON 修复?
LLM 生成的 Tool Call 参数经常有格式问题:
| 问题类型 |
示例 |
修复方案 |
| 格式标记残留 |
`< |
FunctionCallBegin |
| JSON 不完整 |
{"path":"x", |
jsonrepair 库自动补全 |
| 多余后缀 |
{"path":"x"} 好的 |
提取有效 JSON 部分 |
5.5 计划数据模型
1 2 3 4 5 6 7 8 9
| Plan FullPlan (带状态追踪) ┌──────────────────────┐ ┌────────────────────────────────┐ │ Steps: []Step │ │ TaskID: int │ │ ├─ Index: 1 │ → │ Status: todo|doing|done │ │ │ Desc: "读取CSV" │ │ |failed|skipped │ │ ├─ Index: 2 │ │ AgentName: "CodeAgent" │ │ │ Desc: "提取列" │ │ Desc: "读取CSV结构" │ │ └─ ... │ │ ExecResult: *SubmitResult │ └──────────────────────┘ └────────────────────────────────┘
|
状态流转:
1
| todo → doing → done/failed/skipped
|
5.6 上下文参数管理(params/)
使用 context.WithValue + sync.Map 实现线程安全的全局参数共享:
| 键名 |
用途 |
FilePathSessionKey |
输入文件目录路径 |
WorkDirSessionKey |
工作目录(含 UUID 隔离) |
UserAllPreviewFilesSessionKey |
Excel 预览信息(JSON) |
TaskIDKey |
任务唯一标识 |
1 2 3 4 5
| ctx = context.WithValue(ctx, params.WorkDirSessionKey, workDir)
workDir, _ := params.Get(ctx, params.WorkDirSessionKey).(string)
|
5.7 LocalOperator(operator.go)
实现 commandline.Operator 接口,是所有工具的底层执行引擎:
1 2 3 4 5
| type LocalOperator struct{}
func (l *LocalOperator) ReadFile(ctx, path) func (l *LocalOperator) WriteFile(ctx, path, content) func (l *LocalOperator) RunCommand(ctx, command)
|
🔧 关键特性:
- ✅
RunCommand 自动设置 cmd.Dir = workdir,所有命令在工作目录内执行
- ✅ 跨平台支持:
1 2 3 4 5
| /bin/sh -c "command"
cmd.exe /C "command"
|
六、与其他多智能体模式的对比
| 特性 |
Supervisor |
Plan-Execute-Replan |
DeepAgent (本项目) |
| 任务分解 |
动态路由 |
先规划再执行 |
先规划 + 专业子Agent执行 |
| 子Agent |
通用 Agent |
通用 Agent |
专业化 Agent(Code/Search) |
| 工具分配 |
所有Agent共享 |
所有Agent共享 |
按职责分配(主Agent只读,子Agent可写) |
| 状态追踪 |
无 |
有 (步骤级别) |
完整(todo→doing→done/failed/skipped) |
| 输出产物 |
文本回复 |
文本回复 |
结构化产物(report + plan.md + 文件) |
| 错误处理 |
基本 |
可重规划 |
多层恢复(JSON修复 + 工具错误恢复 + 多次迭代) |
| 适用场景 |
简单任务路由 |
需要规划的任务 |
复杂文件处理/数据分析 |
七、数据流全景图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| 用户查询 │ ▼ ┌─ 初始化 ──────────────────────────────────────────┐ │ UUID → 工作目录 → 复制文件 → 预览Excel → 注入Context │ └───────────────────────────┬────────────────────────┘ │ ▼ ┌─ DeepAgent ───────────────────────────────────────┐ │ │ │ ┌─ create_plan ──┐ │ │ │ Step 1: 读取 │ │ │ │ Step 2: 处理 │ │ │ │ Step 3: 验证 │ │ │ │ Step 4: 提交 │ │ │ └────────┬───────┘ │ │ │ │ │ ┌────────▼───────────────────────────────────┐ │ │ │ 循环执行每个 Step: │ │ │ │ │ │ │ │ ┌──────────┐ ┌────────────────────┐ │ │ │ │ │ CodeAgent │ ←→ │ bash/tree/edit/ │ │ │ │ │ │ │ │ read/python_runner │ │ │ │ │ └──────────┘ └────────────────────┘ │ │ │ │ ↕ │ │ │ │ ┌──────────────┐ ┌───────────────────┐ │ │ │ │ │WebSearchAgent│ ←→│ duckduckgo_search │ │ │ │ │ └──────────────┘ └───────────────────┘ │ │ │ │ │ │ │ └─────────────────────────┬───────────────────┘ │ │ │ │ │ ┌─ submit_result ─────────▼──────────────────┐ │ │ │ • final_report.json (结果JSON) │ │ │ │ • plan.md (带✓/☐的计划清单) │ │ │ │ • 生成的输出文件 │ │ │ └────────────────────────────────────────────┘ │ └────────────────────────────────────────────────────┘
|
八、设计亮点总结
🎯 架构设计
| 亮点 |
说明 |
收益 |
| 职责隔离 |
主Agent只读规划,写操作交给CodeAgent,查询交给WebSearchAgent |
降低耦合,提升可维护性 |
| 工具包装模式 |
统一的预处理/后处理管道(WrapTool) |
解决LLM输出不规范问题,提升鲁棒性 |
| JSON自动修复 |
jsonrepair库 + 清除模型格式标记 |
极大提升工具调用成功率 |
🛡️ 安全与隔离
| 亮点 |
说明 |
收益 |
| UUID工作目录隔离 |
每次任务在独立目录执行 |
任务间互不干扰,便于清理 |
| 只读主Agent |
主Agent无写权限工具 |
防止规划阶段意外修改文件 |
📊 可观测性
| 亮点 |
说明 |
收益 |
| Excel预览注入 |
启动时预解析Excel结构(表头、合并单元格) |
Agent规划阶段即可了解数据结构,减少试错 |
| 完整产物输出 |
final_report.json + plan.md + 输出文件 |
可追溯完整执行过程,便于调试和审计 |
| 状态追踪 |
FullPlan 记录 todo/doing/done/failed/skipped |
实时监控任务进度,支持断点恢复 |
🔑 关键要点速记
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ┌─────────────────┬───────────────────────────────────────────┐ │ 要点 │ 说明 │ ├─────────────────┼───────────────────────────────────────────┤ │ 核心模式 │ Plan-Execute:先规划,再委派执行 │ ├─────────────────┼───────────────────────────────────────────┤ │ 职责隔离 │ 主Agent只读规划,子Agent负责具体操作 │ ├─────────────────┼───────────────────────────────────────────┤ │ 工具包装 │ WrapTool统一处理请求/响应,提升鲁棒性 │ ├─────────────────┼───────────────────────────────────────────┤ │ JSON修复 │ jsonrepair + 清除格式标记,解决LLM输出问题│ ├─────────────────┼───────────────────────────────────────────┤ │ 工作目录隔离 │ UUID创建独立目录,任务互不干扰 │ ├─────────────────┼───────────────────────────────────────────┤ │ 状态追踪 │ FullPlan记录每一步状态,支持进度监控 │ ├─────────────────┼───────────────────────────────────────────┤ │ 产物输出 │ JSON报告 + Markdown计划 + 实际文件 │ └─────────────────┴───────────────────────────────────────────┘
|
📌 一句话总结:DeepAgent 通过 Plan-Execute 模式 + 专业化子Agent + 工具包装机制,实现了复杂文件处理任务的可靠编排;理解其职责隔离、状态追踪和产物输出设计,是构建生产级多智能体系统的关键。# DeepAgent 项目分析
📁 项目路径:adk/multiagent/deep/
🎯 核心模式:Plan-Execute(计划-执行) 多智能体编排
一、项目概览
adk/multiagent/deep/ 是一个基于 Eino 框架 deep.New() 预构建 Agent 的多智能体 Excel/文件处理系统。它演示了 Plan-Execute(计划-执行) 模式:
1
| 主 Agent 制定分步计划 → 将每一步委派给专业化的子 Agent 执行
|
🔗 与参考文档 ch04 的关系
参考文档 ch04_tool_backend_filesystem.md |
本项目 adk/multiagent/deep/ |
deep.New() 最简用法 |
deep.New() 高级用法 |
仅配置 Backend + StreamingShell |
手动构建自定义 Tools 和 SubAgents |
| Agent 自动获得文件系统能力 |
展示多智能体编排能力 |
| 适合快速上手 |
适合生产级复杂任务 |
二、目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| adk/multiagent/deep/ ├── main.go # 入口:创建 DeepAgent + Runner,执行查询 ├── operator.go # LocalOperator:文件系统 & 命令执行的本地实现 ├── agents/ │ ├── code_agent.go # 子Agent:代码执行(Python/Bash) │ └── web_search.go # 子Agent:网络搜索(DuckDuckGo) ├── generic/ │ ├── plan.go # Plan / Step 数据结构 + create_plan 工具定义 │ ├── full_plan.go # FullPlan:带状态追踪的完整计划 │ ├── submit_result.go # SubmitResult 数据结构 + 目录遍历 │ └── file_preview.go # Excel 文件预览(解析 xlsx 的表头/内容/合并单元格) ├── tools/ │ ├── wrap.go # 工具包装器:请求预处理 + 响应后处理 │ ├── bash.go # bash 工具:执行 shell 命令 │ ├── edit.go # edit_file 工具:创建/覆盖写文件 │ ├── read.go # read_file 工具:按行读取文件内容 │ ├── tree.go # tree 工具:目录树结构查看 │ ├── python_runner.go # python_runner 工具:写 Python 代码并执行 │ ├── read_image.go # image_reader 工具:通过视觉模型分析图片 │ ├── submit_result.go # submit_result 工具:提交最终执行结果 │ └── option.go # 工具选项(operator 注入) ├── params/ │ ├── consts.go # Context 参数键名常量 │ └── params.go # 基于 sync.Map 的线程安全上下文参数管理 ├── utils/ │ ├── model.go # ChatModel 工厂(支持 ARK / OpenAI) │ └── utils.go # 通用工具函数(JSON修复、格式化等) └── playground/ ├── input/.gitkeep # 输入文件目录 └── test_data/ # 测试数据 ├── questions.csv ├── 推荐小说.txt └── 模拟出题.csv
|
三、三层架构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| ┌──────────────────────────────────────────────────────────────┐ │ Layer 1: 编排层 — DeepAgent (deep.New) │ │ 职责:制定计划 (create_plan) → 逐步委派子 Agent → 提交结果 │ │ 工具:read_file, tree, submit_result, create_plan │ ├──────────────────────────────────────────────────────────────┤ │ Layer 2: 子 Agent 层 │ │ ┌─────────────────────┐ ┌──────────────────────┐ │ │ │ CodeAgent │ │ WebSearchAgent │ │ │ │ • bash │ │ • duckduckgo_search │ │ │ │ • tree │ │ MaxIterations: 10 │ │ │ │ • edit_file │ └──────────────────────┘ │ │ │ • read_file │ │ │ │ • python_runner │ │ │ │ MaxIterations: 1000 │ │ │ └─────────────────────┘ │ ├──────────────────────────────────────────────────────────────┤ │ Layer 3: 基础设施层 │ │ LocalOperator (commandline.Operator 接口) │ │ • ReadFile / WriteFile / RunCommand │ │ params (sync.Map 上下文参数) │ │ utils (JSON修复、模型创建、格式化) │ └──────────────────────────────────────────────────────────────┘
|
四、核心执行流程
🎯 示例查询
1
| "请帮我将 questions.csv 表格中的第一列提取到一个新的 csv 中"
|
🔄 执行流程图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| 用户查询 │ ▼ ┌─ main.go ─────────────────────────────────────────────┐ │ 1. 生成 UUID 作为 TaskID │ │ 2. 创建工作目录 playground/{UUID}/ │ │ 3. 复制输入文件到工作目录 │ │ 4. PreviewPath() 预览 Excel 文件结构 │ │ 5. 初始化 Context 参数(文件路径、工作目录、预览信息) │ │ 6. 创建 Runner 并执行 │ └────────────────────────┬──────────────────────────────┘ │ ▼ ┌─ DeepAgent (Plan-Execute) ────────────────────────────┐ │ ① 分析任务 → 调用 create_plan 生成分步计划 │ │ Plan: [ │ │ {index:1, desc:"读取CSV结构"}, │ │ {index:2, desc:"编写Python提取第一列"}, │ │ {index:3, desc:"执行并验证"}, │ │ {index:4, desc:"提交结果"} │ │ ] │ │ │ │ ② 逐步执行: │ │ Step 1 → 委派 CodeAgent → read_file 读取 CSV │ │ Step 2 → 委派 CodeAgent → python_runner 执行提取 │ │ Step 3 → 委派 CodeAgent → read_file 验证结果 │ │ Step 4 → 调用 submit_result 提交最终结果 │ │ │ │ ③ 输出产物: │ │ • final_report.json (执行结果元数据) │ │ • plan.md (带状态的计划清单) │ │ • 生成的 CSV 文件 │ └────────────────────────────────────────────────────────┘
|
五、关键组件详解
5.1 DeepAgent 创建(main.go:153-194)
1 2 3 4 5 6 7 8 9 10 11 12 13
| deepAgent, err := deep.New(ctx, &deep.Config{ Name: "ExcelAgent", Description: "an agent for excel task", ChatModel: cm, SubAgents: []adk.Agent{ca, wa}, ToolsConfig: adk.ToolsConfig{ Tools: []tool.BaseTool{ tools.NewWrapTool(readFile, nil, nil), tools.NewWrapTool(tree, nil, nil), }, }, MaxIteration: 100, })
|
🎨 设计要点:
| 设计决策 |
目的 |
主 Agent 只配备 read_file 和 tree |
只读权限,仅用于理解文件结构 |
| 写操作和代码执行委派给 CodeAgent |
职责隔离,降低主 Agent 复杂度 |
MaxIteration: 100 |
控制最大循环次数,防止无限执行 |
5.2 CodeAgent(agents/code_agent.go)
1 2 3 4 5 6 7 8 9 10 11 12 13
| adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ Name: "CodeAgent", Description: "specialized in handling Excel files via Python code...", Model: cm, Tools: []tool.BaseTool{ bash, tree, edit_file, read_file, python_runner, }, MaxIterations: 1000, })
|
🔑 关键设计:
- ✅ 通过
GenModelInput 注入工作目录和当前时间到 Prompt
- ✅ 指令明确要求使用
pandas、matplotlib、openpyxl
- ✅ 所有工具都经过
WrapTool 包装,添加了 JSON 修复预处理
5.3 WebSearchAgent(agents/web_search.go)
1 2 3 4 5 6 7
| adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ Name: "WebSearchAgent", Description: "utilizes ReAct model... using web search tools", Model: cm, Tools: []tool.BaseTool{duckduckgo.NewTextSearchTool(...)}, MaxIterations: 10, })
|
💡 最简单的子 Agent,仅用于信息检索场景。
1 2 3 4 5 6 7
| 请求 ──→ [预处理链] ──→ 实际工具执行 ──→ [后处理链] ──→ 响应 │ │ ├─ ToolRequestRepairJSON ├─ FilePostProcess │ (修复LLM生成的损坏JSON) │ (格式化文件变更/stdout/stderr) │ │ └─ 清除 <|FunctionCallEnd|> └─ EditFilePostProcess 等模型格式残留 (简化为 "success" 消息)
|
❓ 为什么需要 JSON 修复?
LLM 生成的 Tool Call 参数经常有格式问题:
| 问题类型 |
示例 |
修复方案 |
| 格式标记残留 |
`< |
FunctionCallBegin |
| JSON 不完整 |
{"path":"x", |
jsonrepair 库自动补全 |
| 多余后缀 |
{"path":"x"} 好的 |
提取有效 JSON 部分 |
5.5 计划数据模型
1 2 3 4 5 6 7 8 9
| Plan FullPlan (带状态追踪) ┌──────────────────────┐ ┌────────────────────────────────┐ │ Steps: []Step │ │ TaskID: int │ │ ├─ Index: 1 │ → │ Status: todo|doing|done │ │ │ Desc: "读取CSV" │ │ |failed|skipped │ │ ├─ Index: 2 │ │ AgentName: "CodeAgent" │ │ │ Desc: "提取列" │ │ Desc: "读取CSV结构" │ │ └─ ... │ │ ExecResult: *SubmitResult │ └──────────────────────┘ └────────────────────────────────┘
|
状态流转:
1
| todo → doing → done/failed/skipped
|
5.6 上下文参数管理(params/)
使用 context.WithValue + sync.Map 实现线程安全的全局参数共享:
| 键名 |
用途 |
FilePathSessionKey |
输入文件目录路径 |
WorkDirSessionKey |
工作目录(含 UUID 隔离) |
UserAllPreviewFilesSessionKey |
Excel 预览信息(JSON) |
TaskIDKey |
任务唯一标识 |
1 2 3 4 5
| ctx = context.WithValue(ctx, params.WorkDirSessionKey, workDir)
workDir, _ := params.Get(ctx, params.WorkDirSessionKey).(string)
|
5.7 LocalOperator(operator.go)
实现 commandline.Operator 接口,是所有工具的底层执行引擎:
1 2 3 4 5
| type LocalOperator struct{}
func (l *LocalOperator) ReadFile(ctx, path) func (l *LocalOperator) WriteFile(ctx, path, content) func (l *LocalOperator) RunCommand(ctx, command)
|
🔧 关键特性:
- ✅
RunCommand 自动设置 cmd.Dir = workdir,所有命令在工作目录内执行
- ✅ 跨平台支持:
1 2 3 4 5
| /bin/sh -c "command"
cmd.exe /C "command"
|
六、与其他多智能体模式的对比
| 特性 |
Supervisor |
Plan-Execute-Replan |
DeepAgent (本项目) |
| 任务分解 |
动态路由 |
先规划再执行 |
先规划 + 专业子Agent执行 |
| 子Agent |
通用 Agent |
通用 Agent |
专业化 Agent(Code/Search) |
| 工具分配 |
所有Agent共享 |
所有Agent共享 |
按职责分配(主Agent只读,子Agent可写) |
| 状态追踪 |
无 |
有 (步骤级别) |
完整(todo→doing→done/failed/skipped) |
| 输出产物 |
文本回复 |
文本回复 |
结构化产物(report + plan.md + 文件) |
| 错误处理 |
基本 |
可重规划 |
多层恢复(JSON修复 + 工具错误恢复 + 多次迭代) |
| 适用场景 |
简单任务路由 |
需要规划的任务 |
复杂文件处理/数据分析 |
七、数据流全景图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| 用户查询 │ ▼ ┌─ 初始化 ──────────────────────────────────────────┐ │ UUID → 工作目录 → 复制文件 → 预览Excel → 注入Context │ └───────────────────────────┬────────────────────────┘ │ ▼ ┌─ DeepAgent ───────────────────────────────────────┐ │ │ │ ┌─ create_plan ──┐ │ │ │ Step 1: 读取 │ │ │ │ Step 2: 处理 │ │ │ │ Step 3: 验证 │ │ │ │ Step 4: 提交 │ │ │ └────────┬───────┘ │ │ │ │ │ ┌────────▼───────────────────────────────────┐ │ │ │ 循环执行每个 Step: │ │ │ │ │ │ │ │ ┌──────────┐ ┌────────────────────┐ │ │ │ │ │ CodeAgent │ ←→ │ bash/tree/edit/ │ │ │ │ │ │ │ │ read/python_runner │ │ │ │ │ └──────────┘ └────────────────────┘ │ │ │ │ ↕ │ │ │ │ ┌──────────────┐ ┌───────────────────┐ │ │ │ │ │WebSearchAgent│ ←→│ duckduckgo_search │ │ │ │ │ └──────────────┘ └───────────────────┘ │ │ │ │ │ │ │ └─────────────────────────┬───────────────────┘ │ │ │ │ │ ┌─ submit_result ─────────▼──────────────────┐ │ │ │ • final_report.json (结果JSON) │ │ │ │ • plan.md (带✓/☐的计划清单) │ │ │ │ • 生成的输出文件 │ │ │ └────────────────────────────────────────────┘ │ └────────────────────────────────────────────────────┘
|
八、设计亮点总结
🎯 架构设计
| 亮点 |
说明 |
收益 |
| 职责隔离 |
主Agent只读规划,写操作交给CodeAgent,查询交给WebSearchAgent |
降低耦合,提升可维护性 |
| 工具包装模式 |
统一的预处理/后处理管道(WrapTool) |
解决LLM输出不规范问题,提升鲁棒性 |
| JSON自动修复 |
jsonrepair库 + 清除模型格式标记 |
极大提升工具调用成功率 |
🛡️ 安全与隔离
| 亮点 |
说明 |
收益 |
| UUID工作目录隔离 |
每次任务在独立目录执行 |
任务间互不干扰,便于清理 |
| 只读主Agent |
主Agent无写权限工具 |
防止规划阶段意外修改文件 |
📊 可观测性
| 亮点 |
说明 |
收益 |
| Excel预览注入 |
启动时预解析Excel结构(表头、合并单元格) |
Agent规划阶段即可了解数据结构,减少试错 |
| 完整产物输出 |
final_report.json + plan.md + 输出文件 |
可追溯完整执行过程,便于调试和审计 |
| 状态追踪 |
FullPlan 记录 todo/doing/done/failed/skipped |
实时监控任务进度,支持断点恢复 |
🔑 关键要点速记
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ┌─────────────────┬───────────────────────────────────────────┐ │ 要点 │ 说明 │ ├─────────────────┼───────────────────────────────────────────┤ │ 核心模式 │ Plan-Execute:先规划,再委派执行 │ ├─────────────────┼───────────────────────────────────────────┤ │ 职责隔离 │ 主Agent只读规划,子Agent负责具体操作 │ ├─────────────────┼───────────────────────────────────────────┤ │ 工具包装 │ WrapTool统一处理请求/响应,提升鲁棒性 │ ├─────────────────┼───────────────────────────────────────────┤ │ JSON修复 │ jsonrepair + 清除格式标记,解决LLM输出问题│ ├─────────────────┼───────────────────────────────────────────┤ │ 工作目录隔离 │ UUID创建独立目录,任务互不干扰 │ ├─────────────────┼───────────────────────────────────────────┤ │ 状态追踪 │ FullPlan记录每一步状态,支持进度监控 │ ├─────────────────┼───────────────────────────────────────────┤ │ 产物输出 │ JSON报告 + Markdown计划 + 实际文件 │ └─────────────────┴───────────────────────────────────────────┘
|
📌 一句话总结:DeepAgent 通过 Plan-Execute 模式 + 专业化子Agent + 工具包装机制,实现了复杂文件处理任务的可靠编排;理解其职责隔离、状态追踪和产物输出设计,是构建生产级多智能体系统的关键。