课程LubanAgent 实战课:8 课从零到部署你的业务 Agent / 第二章 · 核心能力:真模型、工具与知识库 / 第 3 课 接真实模型:槽位映射,换模型不改代码
— 11 min read

第 3 课 接真实模型:槽位映射,换模型不改代码

注册 DeepSeek 到模型工厂并绑到 smart 槽位,让小图按人设说话,亲历真实工具调用与大额退款人工审批,体会换模型只改一条库映射、代码零改动,并从 Trace 算出对话成本。

第 3 课:接真实模型——给小图换上真大脑

学完本课你能:把 DeepSeek(或任一 OpenAI 兼容模型)接进框架并绑到槽位;验证你的 Agent 用真模型按人设说话;看懂一次真实的工具调用和人工审批;解释「换模型 = 改映射,不改代码不发版」为什么成立 | 预计耗时 30 分钟 | 前置:第 2 课(小图已入库) | 难度 ★★☆

从这一课起你需要一个大模型 API Key。推荐 DeepSeek(注册即送额度、充值 10 元足够走完全部教程),通义/智谱/OpenAI 或任何 OpenAI 兼容服务(vLLM/Ollama 自建端点也行)都可以。钱花在哪你会看得清清楚楚——这一课的最后一步教你算每次对话的 Token 成本。

这一课也是前面两课的兑现时刻:小图的身体已经就位,换上真大脑后,你会回去问它"你是谁",看它说出你写的人设;也会重跑第 1 课那条 curl,看事件流里多出来的 tool.started——那一刻"模型说、代码做"就从第 0 课的图变成了你调试台里的现实。

1. 学习目标

  • 注册一个真实模型到模型工厂,绑定到 smart 槽位
  • 验证人设生效、工具调用发生、大额退款走人工审批(完整体验从本课开始)
  • 换绑槽位,观察同一个 Agent 立即换脑、代码零改动
  • 从 Trace 里读出一次对话的 Token 消耗与费用

2. 概念讲解:为什么 Agent 不该写死模型名

设想你把 deepseek-chat 这个模型名直接写死在小图的代码里。三个月后会发生三件事中的一件:

  • DeepSeek 涨价了,你想把日常对话换到便宜的 Qwen——改代码,发版;
  • DeepSeek 服务抖动,你想临时降级到备胎模型——改代码,发版;
  • 来了个视觉任务,需要换多模态模型——又是在同一个地方动刀。

每次都是"改代码 + 发版",而模型选型明明是个运营决策,不是工程决策。

LubanAgent 的解法是中间加一层间接:逻辑槽位。Agent 定义里不写模型名,写的是"我需要哪种档次的大脑"——fast(快而浅)、smart(主力)、cheap(省钱跑量)、vision(多模态)。槽位到具体模型的映射存在数据库里,运行期解析。于是换模型变成了改一条映射记录:Agent 一个字都不用动,新起的对话立即走新模型。

这套机制还有个隐藏好处:计费。注册模型时带上单价(每千 token 输入/输出价格),每次 Run 的 Token 消耗就能换算成钱,按 Agent 归因——你花的每一分钱都查得到出处。

最后交代 FakeLLM 的退场方式:它不会被卸载,只是不再被槽位引用。哪天你想零成本跑链路测试,把槽位指回 fake-chat 就行——假大脑一直在那候着。

3. 动手:主线步骤

步骤 1:配置 API Key

echo 'DEEPSEEK_API_KEY=sk-你的key' >> .env

(Key 从 platform.deepseek.com 注册获取。用其他厂商就配对应的 DASHSCOPE_API_KEY / ZHIPUAI_API_KEY / OPENAI_API_KEY。)

✅ 检查点:grep DEEPSEEK .env 能看到你的 key(这个文件已被 gitignore,不会被提交——任何情况下都不要把 Key 写进代码或 YAML)。

步骤 2:注册模型到模型工厂

服务起着(bash scripts/dev.sh start),然后:

curl -X PUT http://localhost:8000/v1/models -H "Content-Type: application/json" -d '{
  "key": "deepseek-chat", "provider": "deepseek", "model_name": "deepseek-chat",
  "factory": "openai_compat", "api_key_env": "DEEPSEEK_API_KEY",
  "base_url": "https://api.deepseek.com/v1",
  "capability": {"tool_calling": true},
  "params": {"input_price_per_1k": 0.002, "output_price_per_1k": 0.008}
}'

看懂这个请求:api_key_env 说的是"Key 从哪个环境变量读"(不是把 Key 传上来);base_url 是 OpenAI 兼容端点(换成 vLLM/Ollama 就是你的自建地址);params 里两个单价字段供费用归因用(DeepSeek 官方定价,随时可改)。也可以走工作台模型页可视化完成同样的事。

✅ 你应该看到:返回 200 与模型详情。工作台模型页出现 deepseek-chat

步骤 3:绑到 smart 槽位

curl -X PUT http://localhost:8000/v1/brain-mappings -H "Content-Type: application/json" \
  -d '{"profile": "smart", "model_key": "deepseek-chat"}'

✅ 你应该看到:返回 200。查询映射确认:curl http://localhost:8000/v1/brain-mappings?env=dev 里 smart 指向 deepseek-chat。

步骤 4:兑现时刻——问小图是谁

调试台选 my-lib-assistant,输入:你是谁?能帮我做什么?

✅ 你应该看到:一段用你的人设说话的回复——自称小图、列出借阅查询/挂失/规章咨询的服务范围、超范围会建议去前台。和第 1 课的固定台词对比,这就是真大脑的差别。如果你做了第 2 课练习 B(把人设删到只剩一句),先用小图体验一下"人设太薄"的回复有多潦草,再把完整人设 init 回去——这个对比值得亲历一次。

步骤 5:看一次真实的工具调用

customer-service-bot(它有工具),调试台输入:帮我查一下订单 ORD-1001

✅ 你应该看到:回复里出现"无线蓝牙耳机""299 元"这样的真实订单数据——这些数据来自本地 9100 端口的 Mock 业务服务(客服示例的假订单系统)。如果报"连接失败",先起它:

.venv/bin/python -m demos.customer_service.mock_services   # 占终端,建议开新窗口或加 &

再重跑第 1 课那条 curl(curl -N -X POST .../customer-service-bot/runs -d '{"input": "帮我查一下订单 ORD-1001"}'),这次事件流里多出两帧——

event: tool.started      ← 模型决定调 query_order
event: tool.finished     ← 代码真去 9100 拿回了订单数据

第 0 课画的"模型说、代码做",现在在你终端里。

步骤 6:走一次人工审批

/chat 页选 customer-service-bot,输入(退款原因要一起说,模型按 SOP 会先查证):

我要退订单 ORD-1006 的款,899 元,质量有问题,键盘按键失灵

✅ 你应该看到:聊天气泡里出现**「批准 / 拒绝」按钮**——899 元超过 500 元的审批线,refund_apply 是高风险工具,代码拦下执行等人点头。点「批准」,退款真实执行(Mock 服务返回退款单号),对话继续。整个过程在事件流里是 tool.approval.requested → 你点按钮 → tool.approval.resolved

注意谁在拦你:不是模型"自觉"不退款,是代码闸门。第 4 课你会自己写一个这样的高风险工具,approval_required=True 一个参数的事。

步骤 7:换脑演示——改映射不改代码

把 smart 槽位换绑到 fake(演示换脑链路本身):

curl -X PUT http://localhost:8000/v1/brain-mappings -H "Content-Type: application/json" \
  -d '{"profile": "smart", "model_key": "fake-chat"}'

调试台再问小图"你是谁"——回到固定台词。再换回来:

curl -X PUT http://localhost:8000/v1/brain-mappings -H "Content-Type: application/json" \
  -d '{"profile": "smart", "model_key": "deepseek-chat"}'

✅ 你应该看到:两次换绑之间,小图的 YAML、数据库里的定义、代码——一个字都没动过,行为却整个切换了。这就是"换模型 = 改库映射"的实感。(用通义等第二个真实模型绑到 cheap 槽做同样的实验,见练习 A。)

步骤 8:验证重启不打回(重要)

这个坑值得专门验证一次:很多人配好真实模型后,某天重启了服务,发现"怎么回复又变回假台词了"——那是老版本 init 的行为(无条件覆盖槽位)。现在不是了:

bash scripts/dev.sh restart

✅ 你应该看到:重启后再问小图,仍是真模型回复(smart 槽位还是 deepseek-chat,工作台模型页可查)。luban init 的播种只填空位:槽位上有映射就不动,空槽位才填 fake 兜底。重启自由了。

步骤 9:算一次对话的成本

工作台 Traces 页,点开刚才小图那次"你是谁"的 Run。

✅ 你应该看到:Token 消耗(输入/输出)与费用。拿计算器验一下:费用 ≈ 输入 token ÷ 1000 × 0.002 + 输出 token ÷ 1000 × 0.008。一次人设对话大约几厘钱——10 元额度够你把整个教程跑几遍。如果显示 0,检查注册模型时 params 里的单价字段是否填了。

4. 完成自检清单

  • 模型注册进工厂,smart 槽位绑到 deepseek-chat
  • 小图用真模型按人设说话(步骤 4)
  • 事件流里亲眼看到 tool.started / tool.finished(步骤 5)
  • 大额退款在 /chat 走完「审批按钮 → 批准 → 执行」(步骤 6)
  • 换绑槽位两来回,Agent 定义零改动(步骤 7)
  • 重启后真实模型绑定不被打回(步骤 8)
  • Trace 里能读出 Token 与费用(步骤 9)

5. 常见坑

配置后报 CONFIG_ERROR 找不到 Key。 检查 .env 里的变量名与注册模型时的 api_key_env 完全一致(大小写敏感);改完 .env 要重启服务(环境变量在进程启动时读入)。

查订单"连接失败"。 Mock 业务服务(9100)没起。见步骤 5 的说明——dev.sh 不会自动起它,需要单独跑。

退款对话里模型只说不做,没有审批按钮。 看输入里是否带了退款原因——模型按 SOP(查证→算金额→提交)走,信息不全它会先追问而不是直接提交退款工具。这是设计行为,不是故障。

Trace 费用显示 0。 注册模型时没填 input_price_per_1k / output_price_per_1k。补上(PUT 重新注册即可),下一次 Run 就有费用了。

重启后又变假台词。 确认你看到的"假台词"不是第 7 步自己换绑 fake 的残留——查一下当前映射 curl http://localhost:8000/v1/brain-mappings?env=dev。确实是 init 打回去的话,那是遇到了 bug,提 Issue。

6. 练习

练习 A(模仿):注册第二个模型(如 Qwen,需 DASHSCOPE_API_KEY)绑到 cheap 槽位。没有第二个 Key 也没关系——把注册和绑槽操作走一遍(这两步本身不需要 Key 能成功,调用才会报错),体会"加模型"完全不碰 Agent 定义。

练习 B(变式):故意把 .env 里的 Key 改错一位,重启,问小图一个问题。看懂这个报错长什么样、在哪里能看到它(调试台错误提示 / Traces / 服务日志)。在安全环境里学会看报错,是排障能力的起点。改回正确的 Key 再验一次恢复。

练习 C(综合):给你的小图写三档人设——极简(一句话)、当前版、再加一版你认为是"过度详细"的。各 init 一次产生三个版本(用 @version 或版本历史切换对比),问同一个问题,把三次回复的质量差异记两三句话。从此你对"人设要多详细"有自己的手感,而不是听别人说。

7. 小结与下一课预告

小图现在是活的:真大脑、真人设,你也见过了完整的工具调用和人工审批——前两课埋的所有伏笔在这一课全部兑现。你还掌握了槽位机制:换模型是运营操作,一条映射的事。

但小图现在只会说不会做——它的服务范围里写着"借阅记录查询",可它根本没有查询工具(你第 2 课把客服的工具段删了)。下一课给它写真的:一个查借阅记录的低风险工具,一个挂失收工本费的高风险工具(带审批)。加起来二十几行 Python。


延伸阅读:用户手册 §2(模型中心与模型工厂)、§8(成本治理) | 涉及源码:lubanagent/model/brain_resolver.py(槽位解析)、lubanagent/model/openai_compat.py(OpenAI 兼容工厂)

目录