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 手动构建自定义 ToolsSubAgents
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, // 主模型 (temperature=0, 确定性输出)
SubAgents: []adk.Agent{ca, wa}, // 子 Agent 列表
ToolsConfig: adk.ToolsConfig{ // 主 Agent 自身的工具
Tools: []tool.BaseTool{
tools.NewWrapTool(readFile, nil, nil), // 只读 + 目录查看
tools.NewWrapTool(tree, nil, nil),
},
},
MaxIteration: 100,
})

🎨 设计要点:

设计决策 目的
主 Agent 只配备 read_filetree 只读权限,仅用于理解文件结构
写操作和代码执行委派给 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, // temperature=1, topP=1 (创造性更高)
Tools: []tool.BaseTool{
bash, // shell 命令
tree, // 目录结构
edit_file, // 文件编写
read_file, // 文件读取
python_runner, // Python 执行
},
MaxIterations: 1000, // 允许大量迭代完成复杂任务
})

🔑 关键设计:

  • ✅ 通过 GenModelInput 注入工作目录和当前时间到 Prompt
  • ✅ 指令明确要求使用 pandasmatplotlibopenpyxl
  • ✅ 所有工具都经过 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,仅用于信息检索场景。


5.4 工具包装机制(tools/wrap.go)

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) // os.ReadFile
func (l *LocalOperator) WriteFile(ctx, path, content) // os.WriteFile
func (l *LocalOperator) RunCommand(ctx, command) // exec.CommandContext

🔧 关键特性:

  • RunCommand 自动设置 cmd.Dir = workdir,所有命令在工作目录内执行
  • ✅ 跨平台支持:
    1
    2
    3
    4
    5
    // Linux/Mac
    /bin/sh -c "command"

    // Windows
    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 手动构建自定义 ToolsSubAgents
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, // 主模型 (temperature=0, 确定性输出)
SubAgents: []adk.Agent{ca, wa}, // 子 Agent 列表
ToolsConfig: adk.ToolsConfig{ // 主 Agent 自身的工具
Tools: []tool.BaseTool{
tools.NewWrapTool(readFile, nil, nil), // 只读 + 目录查看
tools.NewWrapTool(tree, nil, nil),
},
},
MaxIteration: 100,
})

🎨 设计要点:

设计决策 目的
主 Agent 只配备 read_filetree 只读权限,仅用于理解文件结构
写操作和代码执行委派给 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, // temperature=1, topP=1 (创造性更高)
Tools: []tool.BaseTool{
bash, // shell 命令
tree, // 目录结构
edit_file, // 文件编写
read_file, // 文件读取
python_runner, // Python 执行
},
MaxIterations: 1000, // 允许大量迭代完成复杂任务
})

🔑 关键设计:

  • ✅ 通过 GenModelInput 注入工作目录和当前时间到 Prompt
  • ✅ 指令明确要求使用 pandasmatplotlibopenpyxl
  • ✅ 所有工具都经过 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,仅用于信息检索场景。


5.4 工具包装机制(tools/wrap.go)

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) // os.ReadFile
func (l *LocalOperator) WriteFile(ctx, path, content) // os.WriteFile
func (l *LocalOperator) RunCommand(ctx, command) // exec.CommandContext

🔧 关键特性:

  • RunCommand 自动设置 cmd.Dir = workdir,所有命令在工作目录内执行
  • ✅ 跨平台支持:
    1
    2
    3
    4
    5
    // Linux/Mac
    /bin/sh -c "command"

    // Windows
    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 + 工具包装机制,实现了复杂文件处理任务的可靠编排;理解其职责隔离、状态追踪和产物输出设计,是构建生产级多智能体系统的关键。