第4章 Agent不是魔法,它只是个聪明点的程序
前三章把 Go 环境和核心语法过了一遍。从这一章开始,我们正式进入 Agent 的世界。很多人觉得 Agent 很玄乎——"自主智能体"、"AI 助理"、"下一代的软件形态"……各种高大上的词往外蹦。这一章,我们把 Agent 从神坛上请下来。它不是什么黑科技,它只是一个聪明点的程序——而且你马上就能用 Eino 跑通一个。
4.1 朋友圈里的"Agent"和真Agent,差在哪?
4.1.1 这个词已经被用烂了
打开任何一个 AI 产品的官网,你大概率会看到"Agent"这个词。自动回复的客服叫 Agent,帮你排日程的插件叫 Agent,连一个定时发邮件的脚本都敢叫自己 Agent。
那到底什么才算真正的 Agent?
我们先说一个最简单的判断标准:
如果你告诉它"做什么",它只会做这一件事——那它不叫 Agent,叫"自动化脚本"。
如果你告诉它"目标",它自己想办法、做决定、调用工具来完成——这才叫 Agent。
举个具体的例子。你有一个"每天早上 8 点给我发今日天气"的需求:
自动化脚本的做法:
1. 写一个 cron job
2. 到 8 点,调用天气 API
3. 把返回结果发给你它只能做你规定好的这一件事。你让它"顺便提醒我今天要带伞",它做不到——你没写这个逻辑。
Agent 的做法:
1. 你告诉 Agent 目标:"每天早上提醒我出门要带什么"
2. Agent 自己决定:
- 需要查天气(调用天气 API)
- 需要看你的日程(读取日历)
- 如果下雨 → 提醒带伞
- 如果有户外会议 → 建议涂防晒
- 如果降温 → 提醒带外套
3. 它还会根据你的反馈调整——你说"伞的提醒不用了",下次就不提了Agent 和脚本的核心区别:脚本走的是固定流程,Agent 走的是自主决策。
4.1.2 Agent 的四个必备能力
判断一个系统是不是真正的 Agent,看它有没有这四项能力:
| 能力 | 什么意思 | 没有会怎样 |
|---|---|---|
| 感知 | 能接收输入、理解上下文 | 你跟它说了半天,它当没听见 |
| 规划 | 能把大目标拆成小步骤 | 你说"帮我安排出差",它直接懵了 |
| 行动 | 能调用工具、执行操作 | 永远只给你建议,从不动手 |
| 反思 | 能检查结果、调整策略 | 做错了也不知道改,一直错下去 |
缺任何一项,都不是完整意义上的 Agent。 市面上很多标榜"AI Agent"的产品,其实只有"感知 + 简单行动",缺了规划和反思。这种我们后面会讲,叫"半吊子 Agent"。
4.2 传统程序走流程,Agent 走"想法"
4.2.1 一个订餐的例子
用传统程序和 Agent 分别实现"帮我订个晚餐",差别一目了然。
传统程序:
go
func orderDinner(cuisine string, budget float64, t time.Time) string {
// 第1步:查可用餐厅
restaurants := searchRestaurants(cuisine, budget)
// 第2步:挑第一个
chosen := restaurants[0]
// 第3步:下单
placeOrder(chosen, t)
return fmt.Sprintf("已为您在%s订餐", chosen)
}这个程序的逻辑是你写死的。你规定了"挑第一个餐厅"——即使第一个餐厅评分只有 2 星,它也会订。
Agent:
你:帮我订个晚餐,要清淡一点的,不用太贵
Agent:
1. 理解目标:清淡、不贵、晚餐时间
2. 搜索附近餐厅
3. 筛选:评分高 + 清淡口味 + 人均合理
4. 发现三家合适的,根据你的历史偏好(你上周点过粤菜),推荐粤菜馆
5. 你确认后,自动下单
6. 发现配送费有点贵,换成了到店自取,省了 15 块关键区别:传统程序是"把规则写到代码里",Agent 是"理解目标后自己想办法"。
4.2.2 "不确定性"是 Agent 的特性,不是 bug
传统程序追求"确定性"——同样的输入,永远得到同样的输出。
Agent 正好相反——同样的目标,它可能每次走不同的路径。
比如同样是"帮我查天气",Agent 可能:
- 第一次:直接调天气 API
- 第二次:发现你问的是"明天适不适合跑步",先去查了你的运动偏好,再结合天气和空气质量给了综合建议
这是好事。 说明 Agent 在"思考",在根据上下文调整。你雇一个助理,也不希望他每次都像个机器人一样只做你字面意思上的那件事——你希望他"理解你真正的意图"。
4.3 Agent 是怎么一步步变聪明的?
4.3.1 从 ELIZA 到 GPT-4
Agent 不是一夜之间出现的。它的进化史,就是 AI 一步步获得"感知 → 规划 → 行动 → 反思"能力的过程。
| 时代 | 代表 | 能做什么 | 缺什么 |
|---|---|---|---|
| 1960s | ELIZA | 模式匹配,假装聊天 | 没有任何真正理解 |
| 1990s | 专家系统 | 按规则推理 | 规则靠人写,换个领域就废了 |
| 2010s | Siri / Alexa | 语音识别 + 简单指令 | 只能执行预设命令,不会规划 |
| 2020 | GPT-3 | 能理解自然语言,"很会聊" | 只会说不会做,没有工具 |
| 2022 | ChatGPT | 更好的对话 + 一些插件 | 工具调用还很弱 |
| 现在 | AI Agent | 理解 + 规划 + 行动 + 反思 | 稳定性、安全性还在完善中 |
4.3.2 三个拐点
Agent 真正走向实用的三个关键拐点:
拐点一:LLM 变聪明了。 以前的 AI 你问它"帮我安排明天的行程",它连你要干嘛都听不懂。现在的 LLM 不仅能听懂,还能帮你拆分步骤、做决策。
拐点二:AI 能调用工具了。 Function Calling 让 AI 不再只能"说",它可以真正去查数据库、调 API、执行代码。这是 Agent 从"聊天玩具"到"能干活的助手"最关键的一步。
拐点三:记忆变长了。 早期模型上下文窗口只有几千 token,聊几句就忘了前面说了什么。现在几十万 token 的上下文,Agent 能记住整个项目的对话历史、你的偏好、之前的决策。
4.3.3 Go 赶上这波了吗?
三个拐点里,Go 在"拐点二"之前确实缺席——训练模型、做推理,那是 Python 和 C++ 的天下。但从拐点二开始,大量 AI 基础设施是用 Go 写的:
- Kubernetes 的 AI 调度器(Go)
- 向量数据库的查询引擎(Milvus 的 Go SDK)
- API 网关的智能路由(Go)
- 字节的 Eino 框架(Go)
Go 在 Agent 时代的角色:不是造发动机的,是用发动机造车的。 别人训好了模型,你用 Go + Eino 把它变成能干活的服务——这恰恰是 Go 最擅长的。
4.4 你的 Agent 适合哪种"工种"?
不是所有 Agent 都是全能的。根据应用场景,Agent 大致分成几类:
4.4.1 对话型 Agent
做什么:跟人聊天、回答问题、提供建议。 典型场景:智能客服、法律咨询助手、教育辅导。 核心能力:感知(理解用户意图)+ 简单行动(查询知识库)。 限制:一般不做复杂任务执行,偏"参谋"角色。
4.4.2 任务型 Agent
做什么:接收目标,自主规划步骤,调用工具完成任务。 典型场景:自动化运维、数据分析、代码生成。 核心能力:规划 + 行动为主,反思能力决定了任务完成质量。 特点:这是本书重点讲的类型——真正能干活的那种。
4.4.3 协作型 Agent
做什么:多个 Agent 分工协作,每人管一块。 典型场景:软件开发团队(一个写代码、一个审代码、一个写测试)、多部门数据整合分析。 核心能力:每个 Agent 有自己的角色和职责,需要通信和协作机制。 特点:这个第 9 章会详细展开。Go 的 goroutine + channel 在这里有天然优势——Agent 之间"说话"就是 channel 通信。
4.4.4 陪伴型 Agent
做什么:记住你的习惯、偏好,提供个性化服务。 典型场景:个人助理、健康管家、学习伴侣。 核心能力:长期记忆 + 情景记忆为主。 特点:不强调复杂的任务执行,强调"懂你"。
4.5 用 Eino 跑通第一个 Agent
理论讲完了,是时候写代码了。我们用 Eino 跑一个极简的 Agent,总共不到 30 行。
4.5.1 准备工作
bash
# 初始化项目
mkdir first-agent && cd first-agent
go mod init first-agent
# 安装 Eino
go get github.com/cloudwego/eino@latest4.5.2 第一个 Agent:让它说句话
我们先从最简单的开始——一个 Agent,你问它什么,它回答什么。没有工具、没有记忆、没有规划。但它是你第一个真正用 Eino 跑起来的 Agent。
go
package main
import (
"context"
"fmt"
"os"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/schema"
)
func main() {
ctx := context.Background()
// 第一步:创建 ChatModel(决定用哪个大模型)
chatModel, err := model.NewChatModel(ctx, &model.ChatModelConfig{
Model: "gpt-3.5-turbo",
APIKey: os.Getenv("OPENAI_API_KEY"),
})
if err != nil {
panic(err)
}
// 第二步:创建一个 Chain(把模型包起来)
chain := compose.NewChain[[]*schema.Message, *schema.Message]().
AppendChatModel(chatModel)
// 第三步:编译 Chain
runnable, err := chain.Compile(ctx)
if err != nil {
panic(err)
}
// 第四步:发送消息
input := []*schema.Message{
schema.UserMessage("你好,请用一句话介绍你自己"),
}
output, err := runnable.Invoke(ctx, input)
if err != nil {
panic(err)
}
fmt.Println(output.Content)
}没有 API Key?用 Mock 模式(还记得第 2 章讲的吧):
go
// 用 Mock ChatModel 替代真实模型
type MockChatModel struct{}
func (m *MockChatModel) Generate(ctx context.Context,
input []*schema.Message, opts ...model.Option) (*schema.Message, error) {
return schema.AssistantMessage(
"你好!我是你的 AI Agent 助手(Mock 模式)。准备好了吗?",
), nil
}4.5.3 再加点料:让它能汇报时间
刚才的 Agent 只会聊天,不算真正的 Agent——因为它没有"行动"能力。我们给它加一个工具:获取当前时间。
go
import (
"context"
"fmt"
"time"
"github.com/cloudwego/eino/components/tool"
)
// 定义一个获取时间的工具
type GetTimeTool struct{}
func (t *GetTimeTool) Info(ctx context.Context) (*schema.ToolInfo, error) {
return &schema.ToolInfo{
Name: "get_current_time",
Desc: "获取当前的日期和时间",
}, nil
}
func (t *GetTimeTool) InvokableRun(ctx context.Context,
params string) (string, error) {
now := time.Now()
return now.Format("2006-01-02 15:04:05"), nil
}
func main() {
// ... 创建 ChatModel 的代码同上 ...
// 创建工具
timeTool := &GetTimeTool{}
// 把模型和工具组合成 Agent
agent, err := compose.NewAgent[[]*schema.Message, *schema.Message]().
WithChatModel(chatModel).
WithTools([]tool.InvokableTool{timeTool}).
Compile(ctx)
if err != nil {
panic(err)
}
// 问它时间——它会自己决定调用工具
input := []*schema.Message{
schema.UserMessage("现在几点了?"),
}
output, err := agent.Invoke(ctx, input)
if err != nil {
panic(err)
}
fmt.Println(output.Content)
// 输出:"现在是 2025-03-15 14:30:22"
}这就是一个完整 Agent 的最小骨架——理解意图 + 调用工具 + 生成回答。后面的章节会在这个骨架上,一步步加上记忆、规划、多工具编排。
4.6 本章小结
这一章我们给 Agent"祛魅"了,还顺便跑通了第一个:
- Agent 不是什么魔法:它只是同时具备了感知、规划、行动、反思四项能力的程序。缺了规划和反思的,最多算半吊子。
- Agent 和传统程序完全不同:传统程序走固定流程,Agent 根据目标自主决策。不确定性不是缺陷,是特性。
- Agent 是进化来的:从 ELIZA 到 GPT-4,三大拐点让 Agent 从玩具变成了生产力。Go 在拐点二之后找到了自己的位置——用发动机造车。
- Agent 也分"工种":对话型、任务型、协作型、陪伴型。本书重点讲任务型,用 goroutine + channel 做协作型。
- 你用 Eino 跑通了第一个 Agent:一个能理解问题、调用工具、生成回答的完整 Agent 骨架。
✅ 知识点检查
学完这一章,试试回答这几个问题:
- [ ] 一个真正的 Agent 必须具备哪四项能力?缺了哪一项就不算完整?
- [ ] 传统程序和 Agent 的核心区别是什么?用订餐的例子说明。
- [ ] Agent 进化史上三个关键拐点分别是什么?Go 在哪一阶段开始发力?
- [ ] 任务型 Agent 和对话型 Agent 最大的不同在哪?
- [ ] 用 Eino 创建一个 Agent 需要哪几个步骤?
📚 延伸阅读
- Eino 官方文档:https://www.cloudwego.io/zh/docs/eino/
- Eino GitHub 仓库:https://github.com/cloudwego/eino
- 《Building AI Agents》— Lilian Weng 的博客,Agent 领域最经典的文章之一
- 本书配套源码:关注公众号「图解AI系列」免费领取
🎯 下一章预告
第 5 章,我们给 Agent 装一个大脑——
"LLM 是怎么想事情的?看完这一章,你就知道 Agent 的'思考'到底是怎么回事——以及怎么用 Eino 的 ChatModel 让它'想'得更好。"

