AI Agent 入门实战:Function Calling 让大模型学会调用工具

举报
yd_225040342 发表于 2026/11/03 01:08:15 2026/11/03
【摘要】 用一段可运行的代码,讲清大模型"调用工具"的完整链路与工程落地要点。 一、为什么 Agent 需要工具大模型很擅长理解和生成语言,但它有两个天生短板:知识有截止时间:训练数据之外的信息,它不知道,只能"编"。只能输出文字:无法查询数据库、调用接口、执行操作。把大模型当成一个聪明但"手被绑住"的大脑,**工具调用(Function Calling / Tool Use)**就是给它接上的双手。...

用一段可运行的代码,讲清大模型"调用工具"的完整链路与工程落地要点。

一、为什么 Agent 需要工具

大模型很擅长理解和生成语言,但它有两个天生短板:

  • 知识有截止时间:训练数据之外的信息,它不知道,只能"编"。
  • 只能输出文字:无法查询数据库、调用接口、执行操作。

把大模型当成一个聪明但"手被绑住"的大脑,**工具调用(Function Calling / Tool Use)**就是给它接上的双手。它让模型能查天气、检索知识库、下单、发消息——这才是 Agent 与"聊天机器人"的分水岭。

二、Function Calling 到底做了什么

一个常见误解是"模型会执行函数"。并不会。

模型做的事只有一件:根据你声明的工具描述,判断"该不该调工具、调哪个、参数填什么",然后输出一段结构化的调用意图(函数名 + JSON 参数)。真正的执行由你的程序完成,再把结果回填给模型。

声明工具 → 用户提问 → 模型输出调用意图 → 你的程序执行 → 结果回填 → 模型生成回答

三、一次完整调用流程

以"北京现在天气怎么样"为例:

  1. 声明工具:用 JSON Schema 告诉模型有一个 get_weather 工具,参数是 city。
  2. 模型判断:识别到问题需要实时天气数据,返回 tool_calls:get_weather(city="北京")。
  3. 本地执行:你的代码调用真实天气 API,拿到 {"temp_c": 26, "condition": "晴"}。
  4. 回填结果:把结果以 role: tool 的消息追加到上下文。
  5. 模型收尾:基于工具结果生成自然语言回答;若信息还不够,它会继续发起下一次调用。

关键在于第 2、4 步:模型负责"决策",程序负责"执行",两者职责清晰分离。

四、可运行示例

下面用兼容 OpenAI 风格的接口(主流模型平台大多提供兼容接口)演示,核心逻辑与具体厂商无关。

import json
from openai import OpenAI

client = OpenAI(base_url="https://api.openai.com/v1", api_key="YOUR_API_KEY")

# 1. 声明工具:描述越精确,模型选得越准
tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "查询指定城市的当前天气",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "城市名,例如:北京"}
            },
            "required": ["city"]
        }
    }
}]

# 2. 工具的真实实现(此处用假数据,替换为真实天气 API 即可)
def get_weather(city: str) -> dict:
    return {"city": city, "temp_c": 26, "condition": "晴"}

# 3. 单轮对话主循环
def chat(user_input: str) -> str:
    messages = [{"role": "user", "content": user_input}]

    resp = client.chat.completions.create(
        model="gpt-4o-mini", messages=messages, tools=tools
    )
    msg = resp.choices[0].message

    # 模型没想调工具,直接回答
    if not msg.tool_calls:
        return msg.content

    # 把模型的调用意图写回上下文
    messages.append(msg)

    # 4. 逐个执行工具并回填结果
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        result = get_weather(**args)
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": json.dumps(result, ensure_ascii=False)
        })

    # 5. 再问一次模型,让它基于工具结果作答
    final = client.chat.completions.create(
        model="gpt-4o-mini", messages=messages, tools=tools
    )
    return final.choices[0].message.content

print(chat("北京现在天气怎么样?"))

运行后,你会看到模型先"要"工具,程序执行后再给出自然语言答案。

五、工程落地的最佳实践

demo 能跑不等于能上线。下面这些点决定了 Agent 是否稳定。

1. 工具描述是"第一生产力"。
模型选哪个工具,几乎只依据 description。写清楚"这个工具做什么、什么时候用、参数含义",比调模型参数更有效。

2. 不信任模型给的参数。
模型可能编造字段、给出非法值。参数必须做类型校验、范围校验,必填项缺失就返回结构化错误,让模型重试。

3. 工具数量要克制。
工具越多,模型选错的概率越高。经验上,同一场景超过 10~15 个工具就应考虑拆分或做工具路由。

4. 超时、重试与幂等。
外部接口会超时。给每次调用设超时;对可重试的读操作自动重试;对写操作(下单、扣款)要保证幂等,避免模型重试导致重复执行。

5. 安全是底线。

  • 最小权限:工具只暴露必要能力,绝不让模型直接持有数据库写权限。
  • 危险操作二次确认:删除、支付、发信等,必须由用户或风控确认后再执行。
  • 防提示注入:工具返回的内容可能被恶意构造,不能当作可信指令。

6. 控制对话轮数与上下文。
限制最大调用轮数,防止死循环;工具返回的大结果要截断或摘要,避免上下文爆炸。

7. 可观测。
记录每次工具调用的入参、出参、耗时。出问题时,这是唯一能复盘的东西。

六、几个高频踩坑

现象 根因 对策
模型编造不存在的参数 工具描述含糊 / 缺 Schema 约束 收紧 JSON Schema,补全必填与枚举
选错工具 工具过多、描述重叠 精简工具、区分描述、做路由
陷入反复调用 结果回填格式不对 / 无轮数上限 规范回填、设置最大轮数
回答里出现"函数名" 没把最终结果再交模型总结 执行后务必再请求一次模型
上下文越来越长 原始工具结果过大 截断 / 摘要后再回填

七、小结

Function Calling 的本质是一次职责分工:模型做决策,程序做执行。掌握这条链路后,你就能把大模型接上任意系统,做出真正能做事的 Agent。

下一步可以继续深入的方向:

  • 多工具编排:让 Agent 连续调用多个工具完成复杂任务。
  • ReAct 范式:引入"思考—行动—观察"循环,提升复杂推理能力。
  • RAG:先检索私有知识,再让模型基于检索结果回答,缓解幻觉。

工具调用是 Agent 的地基。先把这一层打扎实,后面的规划、记忆、多智能体协作才有稳定的落脚点。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。