Day 3:加RAG——让Agent有知识
昨天的问题
Day 2 的 Agent 有人设了,但它的"知识"全靠关键词匹配。用户问"你们的退款政策是什么",它只能靠 Mock LLM 瞎猜。
今天做什么
接入 RAG(检索增强生成)。把公司的产品文档、退款政策、常见问题存进知识库,用户提问时先检索相关内容,再让 LLM 基于真实资料回答。
代码
go
package main
import (
"context"
"fmt"
"strings"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/schema"
)
// ===== 知识库:公司文档(模拟) =====
var knowledgeBase = map[string]string{
"退款政策": "我们支持7天无理由退款。退款金额将在3-5个工作日内退回原支付方式。",
"退货流程": "请先提交退货申请,审核通过后将发送退货地址。退回商品需保持原包装完整。",
"配送时效": "全国大部分地区2-3天送达。偏远地区(新疆、西藏等)5-7天。",
"客服时间": "在线客服:每天9:00-22:00。电话客服:工作日9:00-18:00。",
}
// ===== 简易向量检索(模拟语义匹配) =====
func searchKnowledge(query string) string {
var bestMatch string
maxScore := 0
for topic, content := range knowledgeBase {
// 简单的关键词匹配(生产中替换为真正的向量检索)
score := 0
queryWords := strings.Fields(query)
topicWords := strings.Fields(topic)
for _, qw := range queryWords {
for _, tw := range topicWords {
if strings.Contains(qw, tw) || strings.Contains(tw, qw) {
score++
}
}
}
if score > maxScore {
maxScore = score
bestMatch = content
}
}
if bestMatch == "" {
return "未找到相关文档"
}
return bestMatch
}
// ===== 带 RAG 的 Agent =====
type CustomerServiceAgent struct {
model ChatModel
}
type ChatModel interface {
Generate(ctx context.Context,
input []*schema.Message, opts ...model.Option) (*schema.Message, error)
}
func (a *CustomerServiceAgent) Answer(ctx context.Context,
question string) (string, error) {
// 第一步:检索相关知识
context := searchKnowledge(question)
// 第二步:拼接 Prompt
input := []*schema.Message{
schema.SystemMessage(systemPrompt + fmt.Sprintf(
"\n\n你可以参考以下公司文档回答问题。如果文档中没有相关信息,诚实地说不知道。\n\n公司文档:\n%s", context)),
schema.UserMessage(question),
}
// 第三步:让 LLM 基于文档生成回答
result, err := a.model.Generate(ctx, input)
if err != nil {
return "", err
}
return result.Content, nil
}
func main() {
ctx := context.Background()
agent := &CustomerServiceAgent{model: &MockChatModel{}}
questions := []string{
"退款政策是什么?",
"几天能收到货?",
"客服几点下班?",
}
for _, q := range questions {
answer, err := agent.Answer(ctx, q)
if err != nil {
fmt.Printf("❌ 错误: %v\n", err)
continue
}
fmt.Printf("👤 用户: %s\n", q)
fmt.Printf("🤖 小智: %s\n\n", answer)
}
}运行
bash
go run main.go你学到了什么
- RAG 的核心流程:问题 → 检索 → 拼接 → 生成。Agent 不再瞎编,基于真实文档回答。
- 知识库设计:文档按主题组织,检索用关键词匹配(生产中用向量数据库替换)。
- 架构不变:
CustomerServiceAgent.Answer()的接口没变——外部调用方式完全一样,内部加了检索。
明天的预告
Agent 会查文档了,但它还不会"动手"——比如帮用户查订单状态。明天我们给它装上 Eino Tool,让它真正能干活的工具。
Day 3 完成。你的 Agent 现在能查公司文档了。

