Skip to content

第5章 给Agent一个好脑子

第4章讲了Agent是什么——一个能感知、规划、行动、反思的聪明程序。那这个程序最核心的"聪明"从哪来?这一章,我们聊聊Agent的"大脑"——大语言模型(LLM)。不用担心数学公式,我们只讲"它怎么想事情"和"你怎么用Eino跟它说话让它变聪明"。


5.1 LLM是怎么"想事情"的?

5.1.1 别被"大语言模型"这名字吓到

很多人一听"大语言模型"就觉得:肯定要学数学、神经网络、梯度下降……

不需要。

你开车不需要懂发动机原理,你只需要知道踩油门会加速、打方向盘会转弯。用 LLM 也一样——你不用懂 Transformer 架构,你只需要知道:

LLM 本质上就是一个"接话高手"。你给它一段文字,它预测下一个最可能出现的词,一个词一个词接下去,直到把整段话说完。

是不是比你想的简单?它就是一直问自己"根据前文,下一个词大概率是什么",然后挑最可能的那个写上去。

5.1.2 那它为什么能"变聪明"?

"接话"听起来很简单,但当 LLM 读过了几乎整个互联网的文字之后,它"接"出来的话就变得非常有道理了。

比如你输入"帮我写一个Go函数,输入一个slice,返回它的中位数",LLM 能"接"出正确的代码——因为它在训练时见过太多类似的问答了。

关键是:LLM 的"知识"截止到它的训练数据日期。它不知道今天的新闻,不知道你公司的内部文件。这就是为什么 Agent 需要 RAG(第7章)和工具调用(第6章)——补上"实时信息"这块短板。


5.2 Eino ChatModel:一行代码接上大模型

上一章你跑通了第一个 Agent。现在我们来仔细看看 Eino 是怎么跟大模型打交道的。

5.2.1 ChatModel 的配置

Eino 的 ChatModel 屏蔽了不同大模型 API 的差异。换模型对 Agent 代码来说是透明的:

go
import (
    "context"
    "os"
    
    "github.com/cloudwego/eino/components/model"
    "github.com/cloudwego/eino/schema"
)

func main() {
    ctx := context.Background()

    // OpenAI
    openaiModel, _ := model.NewChatModel(ctx, &model.ChatModelConfig{
        Model:  "gpt-4o",
        APIKey: os.Getenv("OPENAI_API_KEY"),
    })

    // 豆包(字节)
    doubaoModel, _ := model.NewChatModel(ctx, &model.ChatModelConfig{
        Model:     "doubao-pro-32k",
        APIKey:    os.Getenv("DOUBAO_API_KEY"),
        BaseURL:   "https://ark.cn-beijing.volces.com/api/v3",
    })

    // DeepSeek
    deepseekModel, _ := model.NewChatModel(ctx, &model.ChatModelConfig{
        Model:   "deepseek-chat",
        APIKey:  os.Getenv("DEEPSEEK_API_KEY"),
        BaseURL: "https://api.deepseek.com",
    })

    // 关键是:不管用哪个模型,调用方式完全一样
    result, _ := deepseekModel.Generate(ctx, []*schema.Message{
        schema.UserMessage("你好"),
    })
    fmt.Println(result.Content)
}

这就是 Go interface 的力量——第 3 章学的,这里用上了。


5.2.2 SystemMessage 和 HumanMessage

和 LLM 对话不是简单的"发一句话"。Eino 区分了三种角色消息:

go
messages := []*schema.Message{
    // SystemMessage:设定 Agent 的角色和行为规范
    schema.SystemMessage("你是一个专业的 Go 代码审查专家。" +
        "请检查代码的潜在问题,并给出改进建议。"),
    
    // HumanMessage:用户的实际输入
    schema.HumanMessage("帮我看看这段代码有什么问题:\n" +
        "func add(a, b int) int { return a - b }"),
}

result, _ := chatModel.Generate(ctx, messages)
消息类型用途例子
SystemMessage设定角色、规则、边界"你是一个代码审查专家"
HumanMessage用户的实际问题"这段代码有什么bug?"
AssistantMessageAI 的历史回复多轮对话时保留上下文

5.2.3 Eino 的 Prompt 模板

和 LangChain 的 PromptTemplate 一样,Eino 也支持模板——动态替换变量:

go
import "github.com/cloudwego/eino/components/prompt"

// 定义模板
template := prompt.FromMessages(schema.FString,
    schema.SystemMessage("你是一个{role}。"),
    schema.HumanMessage("请用{difficulty}的语言解释:{concept}"),
)

// 用的时候替换变量
messages, _ := template.Format(ctx, map[string]any{
    "role":       "物理学老师",
    "difficulty": "通俗易懂",
    "concept":    "量子纠缠",
})
// messages[0]: SystemMessage("你是一个物理学老师。")
// messages[1]: HumanMessage("请用通俗易懂的语言解释:量子纠缠")

5.3 教LLM学会新任务

5.3.1 零样本:直接问,不给例题

最简单的用法——直接问。

你:"把下面这句话翻译成英文:今天天气真好。"
LLM:"The weather is really nice today."

你没有给它任何例子,它照样能做。这叫做零样本(Zero-shot)。LLM 在训练时已经见过足够的翻译数据,所以不需要你教。

但零样本的极限也很明显——遇到复杂任务就懵了。

你:"分析这段Go代码的goroutine泄露风险。"
LLM:(给了一个看起来对但其实没抓到要害的答案)

5.3.2 少样本:给几个例子,让它学着来

当你发现零样本搞不定的时候,给它看几个例子。这就是少样本(Few-shot)

零样本——直接问

你:把下面的用户反馈分类为"好评"、"中评"、"差评"。
反馈:"物流太慢了,东西还行吧。"
LLM:差评(猜错了——其实偏中评)

少样本——先给例子再看

你:请参考以下例子对反馈分类:
例子1:"太棒了,下次还来" → 好评
例子2:"一般般,没啥特别" → 中评
例子3:"质量太差,不会再买" → 差评

现在分类:"物流太慢了,东西还行吧。"
LLM:中评(对了!因为有例子参考)

5.3.3 少样本的实战技巧

技巧 1:例子要典型。 如果你要让 LLM 识别"紧急程度",给的例子要覆盖"紧急"、"普通"、"不急"三种情况,别全给"紧急"的。

技巧 2:例子要简短。 别把一个完整项目文档当例子——LLM 的注意力会分散。3-5 个简短例子效果最好。

技巧 3:例子放最后。 把最重要的例子放在最后——LLM 对离它最近的上下文最敏感。


5.4 思维链与推理增强

5.4.1 "一步一步想"的魔力

LLM 最强的能力不是"给答案",而是"给推理过程"。当你要求它"一步一步想",它的准确率会大幅提升。

不加思维链——直接问

你:小明有3个苹果,小红有2倍于小明的苹果,小刚有小红一半的苹果。三人一共有多少个?
LLM:10个(错了!应该是 3+6+3=12)

加思维链——让它写过程

你:一步步算:小明有3个。小红是小明的2倍=6个。小刚是小红的一半=3个。总共=3+6+3=
LLM:12个(对了!因为它一步一步来,没有跳步)

这就是思维链(Chain of Thought,CoT)——你不需要教它新知识,只需要让它"别急着回答,先写草稿"。

5.4.2 怎么让LLM用思维链

最简单的办法:在 Prompt 里加一句。

请一步一步思考,先写出推理过程,再给出最终答案。

这句话适用于几乎所有的推理任务——数学、逻辑、编程调试、决策分析。

在 Eino 里实现:

go
messages := []*schema.Message{
    schema.SystemMessage("你是一个逻辑推理助手。" +
        "回答问题时,请先写出推理步骤,再给出最终答案。"),
    schema.HumanMessage("一个公司的员工数是80人," +
        "40%是工程师,其中后端占一半。后端有多少人?"),
}

result, _ := chatModel.Generate(ctx, messages)
// LLM 的返回会包含:工程师=80×40%=32人,后端=32÷2=16人,答案:16人。

5.4.3 思维链的边界

思维链不是万能的。它能让 LLM 更准确地推理,但如果 LLM 本身的知识就是错的,思维链只会让它"更自信地犯错"。

所以当你用 LLM 做 Agent 的"大脑"时,不能全信它的推理——需要有工具验证(第6章)、需要给它查资料(第7章)。


5.5 好的Prompt是写出来的,不是想出来的

5.5.1 Prompt就是Agent的"任务说明书"

很多人把 Prompt 当成"随便写一句指令"。其实 Prompt 是你在跟一个超级聪明但完全没有常识的实习生沟通——你说的每一句话,都会影响它的输出质量。

差 Prompt

你:帮我写个函数。(太模糊)
LLM:什么语言?什么功能?什么参数?

好 Prompt

你:用Go写一个函数,输入一个整数slice,返回其中位数。
要求:slice为空时返回0。不用第三方库。
LLM:(给出正确的代码)

5.5.2 Prompt设计的四条铁律

写 Prompt 就像给新员工下任务——说清楚比说得多重要。

铁律一:角色要明确。 告诉 LLM"你是谁"。

你是一个 Go 并发安全审查专家。请审查以下代码的 goroutine 泄露风险。

vs

帮我看看这段代码有什么问题。

前者让 LLM 进入"专家模式",输出质量明显更高。

铁律二:任务要具体。 "帮我写"不如"帮我写一个函数,输入 X 返回 Y"。

铁律三:格式要限定。 如果你需要 JSON,直接说"请以JSON格式返回"。

铁律四:给反例。 告诉 LLM"不要做什么"往往和"要做什么"一样重要。

请写一个友好的回复。不要道歉,不要问"我还能帮你什么",不要超过50个字。

5.5.3 Agent 中的 Prompt 实战

在 Agent 系统中,Prompt 通常被写成一个模板——同样的任务逻辑,用户每次输入的内容不同。Eino 的 prompt.FromMessages 让模板管理变得工程化:

go
import (
    "github.com/cloudwego/eino/components/prompt"
    "github.com/cloudwego/eino/schema"
)

// Agent 的意图识别 Prompt 模板
intentTemplate := prompt.FromMessages(schema.FString,
    schema.SystemMessage("你是一个客服意图识别助手。" +
        "根据用户输入,判断意图是以下哪种:查询订单、申请退款、投诉、其他。" +
        "请只返回意图名称,不要加任何解释。"),
    schema.HumanMessage("用户输入:{user_message}"),
)

// 每次不同用户输入,替换 {user_message}
func classifyIntent(ctx context.Context, userMsg string, 
    model model.ChatModel) (string, error) {
    messages, _ := intentTemplate.Format(ctx, map[string]any{
        "user_message": userMsg,
    })
    result, err := model.Generate(ctx, messages)
    if err != nil {
        return "", err
    }
    return result.Content, nil
}

5.6 本章小结

这一章我们搞清楚了 Agent"大脑"的运作方式:

  1. LLM 就是接话高手:一个词一个词地预测下一个词。但因为见得多,"接"出来的话显得很聪明。
  2. Eino ChatModel 封装:一行代码切换 OpenAI / 豆包 / DeepSeek。SystemMessage 定角色,HumanMessage 提问题。
  3. 少样本学习:给 LLM 几个例子,它就能做复杂任务。例子要典型、简短、重要放最后。
  4. 思维链:让 LLM"一步一步想",准确率暴涨。原理很简单——别让它跳步。
  5. Prompt 设计:角色明确、任务具体、格式限定、给反例。Agent 的 Prompt 就是它的"任务说明书"。
  6. Eino 的 prompt.FromMessages:模板化 Prompt 管理,从此不再跟字符串搏斗。

记住一句话:LLM 是你见过最聪明也最没常识的实习生——你交代得越清楚,它做得越好。


✅ 知识点检查

学完这一章,试试回答这几个问题:

  • [ ] LLM"接话"的过程是怎样的?为什么它看起来像在"思考"?
  • [ ] 零样本和少样本的区别是什么?什么情况下用少样本?
  • [ ] Eino 的 ChatModel 如何做到一行代码切换模型?
  • [ ] 思维链为什么能提高 LLM 的推理准确率?怎么在 Prompt 里触发它?
  • [ ] Prompt 设计的四条铁律分别是什么?

📚 延伸阅读


🎯 下一章预告

第 6 章,Agent 光有脑子还不够——

"光说不练假把式。让 Agent 学会调用工具,它才能真正帮你干活——用 Eino 的类型安全 Tool 系统。"