一句话拆成四步:查天气、筛室内、算路程、排成三天。 前三步是工具,第四步是模型。难点在第二步的参数得从第一步的结果里拿。 顺序也有讲究:先按天气筛,再按距离排。反了就白算。
第 8 章用的是别人写好的 Server,这一章开始自己搭智能体。 七个案例都很小,但每一个都藏着一个具体问题。旅行规划这个藏着的是「参数传递」。 教材这一节是在 Cursor 里配高德 MCP 做的。这一节讲流程,界面操作照原样说明。
一、工作流拆成四步
用户的原话大概是「下周三去杭州玩三天,帮我排一下」。 这句话里没有「查天气」三个字,但要做这件事必须查。 四步:查这三天的天气、按天气挑地点、算地点之间的路程、排成一天一条。 前三步各对应一个工具,第四步没有工具可调——排行程是模型出力。
所以「智能体」这个词在这里的具体含义是:模型自己决定要调三次工具,而不是你写死三次调用。 写死也行,但那叫脚本。区别在于下一步由谁定。
二、第一步:天气是判据,不只是信息
演示里杭州三天:多云、小雨、阴。 这三个词不是给人看的装饰,它们是第二步的输入。「小雨」意味着第二步要挑室内的。 所以第 1 步的输出必须结构化:day、text、low、high 四个字段分开。 如果工具只返回一句「明天小雨 17 到 23 度」,模型还得再解析一遍。
这就是工具设计的一条规矩:能拆成字段的,别拼成一句话。 第 2 章讲过工具返回的形状和资源不一样。这里再补一句:形状也决定了下一歩能不能自动接上。
三、第二步:六个景点筛成两个
演示里杭州六个景点,标了室内的是两个:浙江省博物馆、中国丝绸博物馆。 「室内」这个字段真接口里没有。 演示里是靠名字和类型判的——这一步是替身,替的是「谁来判断」,不是协议。 真机上更靠谱的做法是用类型字段(博物馆、展览馆)加关键词(馆、厅),而不是靠模型逐个猜。
筛完只剩两个,行程就好排了。这一步的价值不是「找地点」,是「把候选砍到能排的量」。 顺带一句:如果筛完一个都不剩,就该退回上一步——「下雨、又没有室内景点」,这时候该告诉用户, 而不是硬排。
四、第三步:路程把顺序定下来
演示里以西湖断桥为起点,算到两个博物馆的直线距离和预计用时。 直线距离乘个系数当车程,是这类工具的常见做法。真接口会给路网距离,这里只算直线。 有了距离,三天的排法就有了依据:同一天去近的两个,别一天横穿全城。
顺序很重要:先按天气筛,再按距离排。 反过来先排好路线、再发现下雨,整条路线要重来。 这也是一句通用的话:先做筛除性的判断,再做优化性的判断。筛除错了只是少几个候选, 优化错了要全部重算。
五、第四步:模型排版,工具帮不上
前三步拿到的东西:三天天气、两个室内景点、两段距离。 第四步要把它变成「第一天上午去哪、下午去哪、第二天……」——这一步没有工具。 教材里这一段是在 Cursor 的对话框里让它直接输出的,配的是高德的 MCP。 (本沙箱没有界面,也没有高德的 Key,流程照原样说明。)
所以这一节要带走的是那个比例:三次工具调用、一段自然语言。工具管事实,模型管编排。 七个案例都是这个比例。「智能」不在工具多,在编排得对。
六、动手 Demo:旅行规划:三个工具轮着调
造一个高德风格的 Server:查天气、找地点、算路程三个工具。 按真实顺序跑一遍,看每一步的输出怎么变成下一步的参数。 「下雨所以挑室内」这一步在真机上是模型判断,这里换成一条筛选,说明在哪一行替的。
amap = Server('amap-mcp')
amap.add(Tool('weather.forecast', '查某城市某几天的天气', SCHEMA, fn))
amap.add(Tool('poi.search', '按城市和类型找地点', SCHEMA, fn))
amap.add(Tool('route.plan', '给起点终点,返回距离和用时', SCHEMA, fn))
w = call(amap, 'weather.forecast', {'city': '杭州', 'days': 3})
rainy = [x['day'] for x in w['items'] if '雨' in x['text']] # 模型判断
ps = call(amap, 'poi.search', {'city': '杭州', 'type': '景点'})['items']
keep = [x for x in ps if x['indoor']] # 模型判断
km = call(amap, 'route.plan', {'from': '西湖断桥', 'to': keep[0]['name']})
print(km)
实跑输出:
--------------------------------------------------------------------
旅行规划:三个工具轮着调
--------------------------------------------------------------------
① 一句话拆成四步
--------------------------------------------------------------------
| 步 | 要什么 | 调哪个工具 | 用掉了什么 |
|---:|---|---|---|
| 1 | 这三天的天气 | weather.forecast | 城市、日期 |
| 2 | 雨天能去的室内景点 | poi.search | 第 1 步的天气结果 |
| 3 | 景点之间怎么走 | route.plan | 第 2 步选中的地点 |
| 4 | 排成一天一条 | 不调工具,模型自己排 | 前三步全部结果 |
四步里只有前三步是协议的事。第四步是模型出力,没有工具可调。
所以「旅行规划智能体」的难点不在工具,在【第 2 步的参数得从第 1 步的结果里拿】。
② 第 1 步:查天气
--------------------------------------------------------------------
| 哪一天 | 天气 | 最低 | 最高 |
|---|---|---:|---:|
| 今天 | 多云 | 19 | 27 |
| 明天 | 小雨 | 17 | 23 |
| 后天 | 阴 | 18 | 25 |
这一步的输出里有一栏「天气」。它就是下一步的判据:小雨,所以第 2 步要挑室内的。
③ 第 2 步:只挑室内的
--------------------------------------------------------------------
天气里带「雨」的是:明天。所以这一次要室内的。
| 地点 | 评分 | 门票 | 室内 |
|---|---:|---:|---|
| 西湖断桥 | 4.8 | 0 元 | 否 |
| 灵隐寺 | 4.7 | 75 元 | 否 |
| 浙江省博物馆 | 4.6 | 0 元 | 是 |
| 中国丝绸博物馆 | 4.5 | 0 元 | 是 |
命中 4 条,其中室内 2 条(浙江省博物馆、中国丝绸博物馆)。
「室内」这个字段真接口里没有,得靠类型和名字判。
【这一步的判据是替身,但替的是「谁来判断」,不是协议。】
④ 第 3 步:算路程
--------------------------------------------------------------------
| 从西湖断桥到 | 直线距离 | 预计用时 |
|---|---:|---:|
| 浙江省博物馆 | 0.5 公里 | 6 分钟 |
| 中国丝绸博物馆 | 3.4 公里 | 15 分钟 |
直线距离乘个系数当车程,是这类工具的常见做法。真接口会给路网距离,这里只算直线。
注意顺序:先按天气筛,再按距离排。【顺序反过来就白算了】——先把远的排前面,再发现下雨,还得重来。
⑤ 四步连起来长什么样
--------------------------------------------------------------------
用户:下周三去杭州玩三天,帮我排一下
模型:weather.forecast(city=杭州, days=3) -> 明天小雨
模型:poi.search(city=杭州, type=景点) -> 6 条,室内 2 条
模型:route.plan(from=西湖断桥, to=浙江省博物馆) -> 3.3 公里
模型:把上面三样排成三天,写成人话
三行工具调用、一行自然语言。【这就是一个「智能体」的全部结构】,剩下的都是提示词和排版。
第 9 章后面六个案例都是这个形状,只是工具换了。
①第一张表四行,第四行写着「不调工具,模型自己排」。这一行是很多人漏掉的——以为每一步都得有工具。 ②天气那张表三个字段分开,就是为了让下一步能自动接上。拼成一句话的话,模型还得再解析一次。 ③第二张表六个景点,室内两个。注意右边那一列「室内」是判出来的,真接口里没有这个字段。 ④第三张表两行距离,它是排行程的唯一依据。没有距离,「同一天去近的」这句话就落不了地。 ⑤最后那个「四步连起来」的框,是这一节要背下来的形状:三行工具、一行人话。 下一节那个约会助手也是这个形状。
30 秒实验
- 把杭州换成宜昌,重跑一遍,看室内的还剩几个。一个都不剩的时候,你会怎么答。
- 给 weather.forecast 加一个「降水概率」字段,看行程能不能排得更细。
- 把「先筛后排」改成「先排后筛」,数一下要重算几次。
常见误区
- 「每一步都要有工具。」排行程这一步没有工具,是模型出力。工具管事实,模型管编排。
- 「天气查了是为了告诉用户。」它是判据,决定下一步挑室内还是室外。
- 「先排路线再看天气也一样。」下雨要换地点,路线全废。筛除性的判断要先做。
自测三问(点开对答案)
1. 旅行规划的四步,哪一步没有工具? —— 第四步排行程。前三步查天气、找地点、算路程都有工具,排版是模型出力。 2. 为什么工具返回要拆成字段,别拼成一句话? —— 拆成字段下一步才能自动接上。「小雨」要能被程序读到,不能只出现在一句话里。 3. 为什么先筛天气再排路线? —— 筛除错了只是少几个候选;优化错了要全部重算。筛除性的判断先做。一个案例一个 Server。下一个案例换成三个 Server 一起干活,看合并工具表之后会多出什么问题。
- ☐ (本篇完,下一篇 9.2 约会助手智能体)