ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Agent 开发入门:Function Call 实战

2026/8/10 11:12:40 拓冰建站 浏览量
Agent 开发入门:Function Call 实战

接上篇《RAG 优化实战》。RAG 让模型"有资料可答",Function Call 让模型"能动手干活"——这是 Agent 的地基。今天讲透两种实现:原生 API + 手动 Prompt。

目录

一、Function Call 是什么

二、两种实现方式

方式A:原生API自动调用(框架帮你编排)

方式B:手动Prompt拼JSON(理解原理)

三、完整可运行代码

四、工具设计原则

五、过关清单

六、常见坑

七、下一步:从Function Call到Agent


一、Function Call 是什么

模型不会真的去查天气,它只会"说:我想调天气工具,参数是北京"。真正执行的是你的代码,执行完把结果塞回对话,模型再总结成自然语言。

用户提问 → 模型选工具+填参数 → 你的代码执行 → 结果塞回对话 → 模型总结回答

后端类比:模型=会自己选路由的Controller,执行权在你手里(你是Service层)

二、两种实现方式

方式A:原生API自动调用(框架帮你编排)

工具描述成JSON Schema随消息发给模型,模型选工具你执行。类比Spring @Autowired

方式B:手动Prompt拼JSON(理解原理)

提示词里写"可输出{"action":"..","params":{..}}",自己json.loads+switch分发。

价值:手动写一遍才真懂底层原理,面试讲原理不心虚;还能跑在不支持function call的模型上

三、完整可运行代码

def native_fc(question: str) -> str: """方式 A:原生 Function Call(框架帮你编排)。""" msgs = [{"role": "user", "content": question}] resp = client.chat.completions.create( model=FC_MODEL, messages=msgs, tools=TOOL_SCHEMAS ) msg = resp.choices[0].message if msg.tool_calls: # 把模型的"我想调工具"这条消息原样塞回去 msgs.append(msg.model_dump()) for call in msg.tool_calls: name = call.function.name args = json.loads(call.function.arguments) result = TOOLS_IMPL[name](**args) # 执行权在你:你跑,模型不跑 msgs.append({ "role": "tool", "tool_call_id": call.id, "name": name, "content": str(result) # 强制转字符串,防止JSON类型错误 }) # 结果塞回对话后,再让模型总结成自然语言 final = client.chat.completions.create(model=FC_MODEL, messages=msgs) return final.choices[0].message.content return msg.content
def manual_fc(question: str) -> str: """方式 B:手动 Prompt(自己拼 JSON + 分发执行)。""" msgs = [ {"role": "system", "content": MANUAL_SYS}, {"role": "user", "content": question}, ] resp = client.chat.completions.create( model=FC_MODEL, messages=msgs, response_format={"type": "json_object"} ) out = resp.choices[0].message.content try: decision = json.loads(out) # 自己解析模型吐出的 JSON name = decision.get("action") if name in TOOLS_IMPL: # switch 分发:按 action 找到对应函数执行 result = TOOLS_IMPL[name](**decision.get("params", {})) msgs += [ {"role": "assistant", "content": out}, {"role": "user", "content": f"工具返回:{result},请据此回答。"}, ] final = client.chat.completions.create(model=FC_MODEL, messages=msgs) return final.choices[0].message.content except Exception as e: return f"解析失败:{e}" return out

效果:问"北京今天多少度加3等于几"→模型自动调天气(25度)+计算(25+3=28)→输出"北京25度,加3等于28"

四、工具设计原则

单一职责(一工具一事)|参数清晰(类型/说明/范围)|结构化返回|执行权在你

五、过关清单

☐ 系统提示词让模型稳定按指定格式回答

☐ 原生FC:复合问题选≥2工具并按序调用

☐ 手动版:能解析JSON并正确执行工具

☐ 能讲清"原生vs手动"区别和适用场景

☐ 工具出错时模型能换工具或告知用户

六、常见坑

1. description写含糊→选错工具(写清含义/举例)

2. 工具返回一坨原始数据→裁剪成精简摘要

3. 模型输出不合法JSON→正则抽取或response_format强约束

4. 执行结果直接当答案→让模型再总结一轮

5. 写操作没确认→危险操作加白名单/人工确认

七、下一步:从Function Call到Agent

Function Call是"单次调用工具"。升级成循环(思考→行动→观察→再思考)就是Agent:ReAct循环。

下一篇预告:《Agent开发:ReAct循环与工具调用实战——从单次调用到自主Agent》。欢迎关注专栏,持续更新。

👉 关注公众号「程序员AI工坊」,回复「避坑」,免费领《后端转AI落地避坑清单》(8 个核心坑全文)。

📌 配套代码:(Star支持🔥

https://github.com/cxy-ai-gongfang/backend-to-ai-guide/blob/main/function-call-demo/README.md