
引子
上回说到,零零发的 "密探发明聊天棚" 虽已初具雏形,却卡在了最关键的一步 ------ 工具调用结果没法传给军师。
在本篇京城八卦中,您将学到如下内容:
- 引子
- 🔄 第五回:打通任督二脉!工具结果传给军师
- 🧪 第六回:实战演练!看看神器好不好使
- 第一步:密探发问
- 第二步:军师接招
- 第三步:调用工具
- 第四步:结果回传
- 第五步:军师总结
- 🚀 第七回:查漏补缺!这些坑可别踩
- 🎭 终章:神器大成,零零发的 "发明哲学"
就像他那 "要你命三千" 明明装好了十八般兵器,却忘了装发射按钮,急得零零发抓耳挠腮:"岂有此理!这就好比跟无相皇打架,都掏出刀了却发现没开刃,岂不是贻笑大方?:("

🔄 第五回:打通任督二脉!工具结果传给军师
零零发蹲在地上画了三个圈:"第一步,军师让调用工具;第二步,咱们调用工具拿结果;第三步,把结果塞回给军师。这三步环环相扣,少一步都成不了事!" 说着就在sendMessage
里补全了逻辑,活像给断了的经脉接上线。
看看这补全的代码,每一步都透着零零发的 "发明智慧":
swift
// 完善后的发送消息方法(新增处理工具调用的逻辑)
func sendMessage() {
// 上集已有代码:添加用户消息、清空输入框、开始加载
let userMessage = Request.Message(role: .user, content: [.text(text: inputText)])
messages.append(ChatMessage(message: userMessage))
inputText = ""
isLoading = true
let allMessages = messages.map(\.message)
Task {
do {
let advisorResponse = try await advisorService.send(messages: allMessages)
let assistantMessage = ChatMessage(
message: Request.Message(role: .assistant, content: advisorResponse.content)
)
self.messages.append(assistantMessage)
// 新增:遍历军师的回复,看看有没有让调用工具
for content in advisorResponse.content {
switch content {
case .toolUse(let toolId, let toolName, let input):
// 调用工具,并把结果回传给军师(这步是关键!)
try await useTool(toolId: toolId, toolName: toolName, input: input)
case .text, .toolResult:
continue // 其他类型的消息不用处理
}
}
} catch {
print("出错啦!零零发:'哎呀,零件掉了!' 错误:\(error)")
}
isLoading = false
}
}
// 新增:调用工具并回传结果给军师的方法
private func useTool(toolId: String, toolName: String, input: [String: String]) async throws {
// 1. 找对应的工具(总不能张冠李戴,拿查发明的工具去测暗器吧)
guard let tool = inventionServer.tools.first(where: { $0.name == toolName }) else {
print("没找到工具:\(toolName),零零发:'这零件我好像没见过啊?'")
return
}
// 2. 调用工具拿结果(相当于按动"要你命三千"的发射按钮)
let toolResult = try await inventionServer.call(tool)
print("工具返回结果:\(toolResult),零零发:'成了!'")
// 3. 把结果包装成"工具结果消息",加到聊天记录里
let toolResultMessage = Request.Message(
role: .user, // 注意:工具结果也得算用户这边的消息,不然军师不认
content: [.toolResult(toolUseId: toolId, content: toolResult)]
)
self.messages.append(ChatMessage(message: toolResultMessage))
// 4. 把包含工具结果的所有消息再发给军师,让他接着分析
let allMessages = self.messages.map(\.message)
let finalResponse = try await advisorService.send(messages: allMessages)
let finalMessage = ChatMessage(
message: Request.Message(role: .assistant, content: finalResponse.content)
)
self.messages.append(finalMessage)
}
零零发拍着胸脯说:"瞧见没?这useTool
方法就是打通任督二脉的关键!工具结果必须带toolUseId
,跟军师发的 ID 对上,不然他老人家哪知道这结果是哪个请求的?就像给皇上递奏折,得标上编号,不然皇上哪记得你上次说的是啥!"

🧪 第六回:实战演练!看看神器好不好使
代码写完了,零零发搓着手说:"是骡子是马拉出来遛遛!咱们模拟个场景 ------ 我问军师'我的天外飞仙破解器状态如何?',看看它能不能自动查、自动答。"
第一步:密探发问
输入框敲上:"军师,我那天外飞仙破解器咋样了?能对付无相皇不?" 点发送。此时 APP 把消息发给 Claude,附带可用工具列表。

第二步:军师接招
Claude 收到消息,一看是查发明状态,立马回复:"稍等,我这就调用工具查查您的天外飞仙破解器状态。" 同时偷偷发了个工具调用指令(藏在 JSON 里,用户看不见):
json
{
"content": [
{
"type": "text",
"text": "我这就帮您查查天外飞仙破解器的状态..."
},
{
"type": "tool_use",
"id": "toolu_007", // 工具调用ID,等会儿结果要用
"name": "check_latest_invention",
"input": {}
}
]
}

第三步:调用工具
APP 检测到tool_use
指令,立马调用check_latest_invention
工具,从 "密探发明库" 拿到结果:"天外飞仙破解器:电量80%,状态:已校准"
。

第四步:结果回传
APP 把结果包装成tool_result
消息,发给军师:
json
{
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_007", // 必须跟之前的ID对上
"content": "天外飞仙破解器:电量80%,状态:已校准"
}
],
"role": "user"
}
第五步:军师总结

Claude 收到结果,整理成人话回复:"回禀密探,您的天外飞仙破解器目前电量 80%,已校准完毕,对付无相皇绰绰有余!不过记得打完架充个电,免得下次急用。"
零零发看着完整的聊天记录,笑得合不拢嘴:"完美!这流程比我给琴操姑娘修胭脂盒还顺!从发问、调用工具到拿到答案,一气呵成,简直是'居家旅行、杀人灭口'之必备神器啊!"

🚀 第七回:查漏补缺!这些坑可别踩

零零发毕竟是老江湖,知道新发明总有小毛病,特意列了几个 "避坑指南":
-
权限问题
"调用'密探发明库'得先申请权限,不然就像没带腰牌想进皇宫 ------ 门儿都没有!" 务必在 Info.plist 里加好描述,不然 APP 会闪退。
-
角色别搞反
"用户发的消息角色是
user
,军师是assistant
,工具结果也算user
这边的。搞错了角色,军师就会像被点了穴 ------ 一动不动,还报错给你看!" -
tool_use_id 要对应
"工具结果的 ID 必须跟军师发的对上,就像暗器上的标记,错了就会乱开枪!" 要是 ID 对不上,Claude 会一脸懵:"这结果是啥玩意儿?我没问过啊!"
-
异常处理不能少
"万一工具调用失败,比如没数据,得告诉用户'查不到哦',别让 APP 直接崩溃。就像我那发明偶尔卡壳,总得有个'重启按钮'吧?"
🎭 终章:神器大成,零零发的 "发明哲学"

零零发把 "密探神器" 往桌上一放,对着镜头感慨道:"你看这 MCP 协议,不就是给 APP 装了个'会思考的脑子'吗?以前的 APP 是'你问一句,它答一句',现在倒好,它会自己找工具、查数据,跟个小密探似的!"
他拿起 "天外飞仙破解器" 比划着:"这就像我当年发明武器,不光要能打,还得会'思考'------ 敌人来了,它自动选刀还是选枪。做 APP 也一样,光有界面不够,得让它懂用户、会办事,这才是'智能'的真谛啊!"

最后,零零发凑近屏幕,挤眉弄眼道:"记住了啊,搞开发就像追姑娘 ------ 得懂她心思,还得有手段。MCP 就是你的'泡妞秘籍',用好了,你的 APP 能跟用户聊得眉来眼去,比我跟琴操姑娘还投缘呢!"

要知零零发与琴操姑娘后事如何?我们下次再叙喽。
感谢宝子们的观赏,再会啦!8-)