第9章 一个人不行?组个团
前面几章我们一直在打造一个全能Agent——脑子好、手脚快、记性好、会规划。但现实中,一个Agent再强也有天花板。就像你不会让一个人同时当销售、财务、程序员和客服——你得组团队。这一章,我们讲Multi-Agent协作。Go的goroutine + channel在这个场景里是天然优势。
9.1 一个Agent忙不过来?那就多找几个
9.1.1 一个全栈Agent的困境
假设你要做一个"智能软件开发助手",它需要:
- 理解需求(产品经理的活)
- 写代码(程序员的活)
- 审查代码(Code Review的活)
- 写测试(测试工程师的活)
- 写文档(技术写作的活)
全塞给一个Agent?它的Prompt会变得又长又乱,工具列表爆炸,一不留神就搞混角色——明明在写代码,突然跳到审查模式。
每人只干一件事?更靠谱。五个Agent,各司其职。
9.1.2 什么时候该用Multi-Agent
简单判断标准:如果一个人能干的活,用一个Agent;如果需要不同角色配合的活,用Multi-Agent。
9.2 多Agent怎么配合?
9.2.1 三种经典架构
层级模式(Supervisor):有一个"总监"Agent,负责分配任务、检查结果、做最终决策。
总监Agent:用户想做一个登录功能。
Agent A(前端):你负责写登录表单。
Agent B(后端):你负责写登录接口。
Agent C(测试):等A和B完成后,你负责写测试用例。流水线模式(Pipeline):每个Agent处理完交给下一个。适合有明确步骤的任务。
Agent A(数据清洗)→ Agent B(数据分析)→ Agent C(报告生成)平行模式(Parallel):多个Agent同时干活,互不依赖。这是Go最擅长的场景。
Agent A 查天气 →
Agent B 查新闻 → 同时进行,结果汇总
Agent C 查股价 →9.3 Eino多Agent:goroutine让它们真的并行
9.3.1 平行模式:goroutine同时跑
Python 做平行模式靠 asyncio 或线程池,Go 一个 go 关键字就搞定——而且是真正的并行:
go
// 三个 Agent 同时执行,互不等待
func parallelQuery(ctx context.Context, question string) map[string]string {
results := make(chan QueryResult, 3)
// 同时启动三个 Agent
go func() {
results <- QueryResult{"天气", weatherAgent.Ask(ctx, question)}
}()
go func() {
results <- QueryResult{"新闻", newsAgent.Ask(ctx, question)}
}()
go func() {
results <- QueryResult{"股价", stockAgent.Ask(ctx, question)}
}()
// 收集结果
output := make(map[string]string)
for i := 0; i < 3; i++ {
r := <-results
output[r.Source] = r.Content
}
return output
}Python 的 asyncio.gather 也能并发,但在多核 CPU 上 Go 的 goroutine 能做到真正的并行——Python 的 GIL 决定了 asyncio 只是"看起来同时"。
9.3.2 层级模式:Eino Graph 实现 Supervisor
用 Eino Graph 实现层级模式——Supervisor节点 + 条件路由:
go
graph := compose.NewGraph[AgentState, AgentState]()
// 添加节点
graph.AddNode("supervisor", supervisorNode) // 总监:决定下一步找谁
graph.AddNode("researcher", researcherNode) // 研究员:查资料
graph.AddNode("coder", coderNode) // 程序员:写代码
graph.AddNode("reviewer", reviewerNode) // 审查员:检查代码
// 总监根据结果路由
graph.AddConditionalEdge("supervisor", func(ctx context.Context,
state AgentState) (string, error) {
if state.ResearchDone && state.CodeDone && state.ReviewDone {
return compose.END, nil
}
if !state.ResearchDone {
return "researcher", nil
}
if !state.CodeDone {
return "coder", nil
}
return "reviewer", nil
})
// 每个 Worker 干完活回总监
graph.AddEdge("researcher", "supervisor")
graph.AddEdge("coder", "supervisor")
graph.AddEdge("reviewer", "supervisor")9.3.3 流水线模式:Chain 天然支持
流水线不需要 Graph,Chain 就是天然的流水线:
go
pipeline := compose.NewChain[TaskInput, FinalReport]().
AppendLambda(dataCleaner). // 数据清洗
AppendLambda(dataAnalyzer). // 数据分析
AppendLambda(reportGenerator) // 报告生成9.4 Agent之间怎么"说话"?
9.4.1 在Go里,Agent说话就是channel通信
Python 多Agent通信靠消息字典、共享黑板、事件总线。Go 有更简单的方式——channel。
go
// Agent 之间的消息
type AgentMessage struct {
From string
To string
Type string // request / response / notify
Content string
}
// 前端 Agent 给后端 Agent 发消息
frontendChan := make(chan AgentMessage, 10)
backendChan := make(chan AgentMessage, 10)
// 前端 Agent
go func() {
backendChan <- AgentMessage{
From: "前端Agent",
To: "后端Agent",
Type: "request",
Content: "需要你提供一个 /api/login 接口",
}
}()
// 后端 Agent 收到消息后处理
msg := <-backendChan9.4.2 三种通信方式
| 通信方式 | Go 实现 | 适合场景 |
|---|---|---|
| 点对点 | 两个 goroutine 之间的 channel | 固定搭档 |
| 广播 | sync.Cond 或 多个 channel 写入 | 通知所有人 |
| 共享状态 | sync.Map 或带锁的结构体 | 进度追踪 |
go
// 共享状态——所有 Agent 往同一个地方读写
type Blackboard struct {
mu sync.RWMutex
Status map[string]string
}
func (b *Blackboard) Update(agent, status string) {
b.mu.Lock()
defer b.mu.Unlock()
b.Status[agent] = status
}
func (b *Blackboard) Read() map[string]string {
b.mu.RLock()
defer b.mu.RUnlock()
return b.Status
}9.5 意见不合怎么办?
9.5.1 多Agent一定会吵架
两个Agent给出矛盾的建议很正常:
Agent A(成本优先):建议用SQLite,零配置,够用。
Agent B(性能优先):建议用PostgreSQL,并发强,可扩展。这不是bug,这是多Agent系统的特性。不同Agent有不同的"视角"和"偏好"。
9.5.2 解决冲突的三种方式
方式一:投票。 三个以上的Agent,少数服从多数。
go
func vote(opinions []Opinion) string {
tally := make(map[string]int)
for _, o := range opinions {
tally[o.Choice]++
}
// 找最高票
var winner string
max := 0
for choice, count := range tally {
if count > max {
winner, max = choice, count
}
}
return winner
}方式二:总监裁决。 层级模式下,总监Agent做最终决定。
总监Agent:A说的有道理,项目初期SQLite够了。但我们预期用户量会快速增长,
B的考虑也很重要。折中方案:先用SQLite开发,但数据层加抽象接口。方式三:辩论后共识。 让不同意见的Agent各自陈述理由,再综合出最优解。
9.6 本章小结
这一章我们突破了"单Agent"的思维:
- 什么时候用Multi-Agent:任务可分拆、需要不同能力时。全栈Agent不如专业Agent团队。
- 三种协作模式:层级(有总监)、流水线(接力棒)、平行(各干各的)。Go的goroutine让平行模式真正并行。
- Eino 实现:平行模式用goroutine+channel,层级模式用Graph条件路由,流水线用Chain。
- Agent通信:点对点用channel,广播用sync.Cond,共享状态用sync.Map——Go的标准库就够用了。
- 意见不合是正常的:投票、总监裁决、辩论后共识——和人类团队解决问题的方式一模一样。
✅ 知识点检查
学完这一章,试试回答这几个问题:
- [ ] 什么情况下该用Multi-Agent而不是单Agent?
- [ ] 层级、流水线、平行三种模式各适合什么场景?Go在哪一种上有天然优势?
- [ ] Eino Graph 如何实现 Superisor 模式?
- [ ] Agent之间有哪三种通信方式?Go用什么实现?
- [ ] 两个Agent意见不合时,有哪三种解决方法?
📚 延伸阅读
- Eino Graph 文档:https://www.cloudwego.io/zh/docs/eino/
- Go 并发模式:https://go.dev/blog/pipelines
- 本书配套源码:关注公众号「图解AI系列」免费领取
🎯 下一章预告
第10章,Agent框架那么多,到底该学哪个——
"巨人的肩膀就在那,挑哪个站?Eino、LangChainGo、自己撸——一次讲清楚,帮你做选择。"

