Function Calling:让大模型连接真实世界

Function Calling:让大模型连接真实世界

AI 核心技能系列 · 第 6 篇


导语

大模型能"思考"和"说话",但不能"动手"------它不能查数据库、调接口、发邮件、买机票。

Function Calling(函数调用) 就是给大模型装上"手"的技术。它让模型能够决定调用哪个函数、传什么参数,然后由应用程序执行函数,把结果返回给模型,模型再据此生成最终回答。

这是 Agent 的核心基础------没有 Function Calling,Agent 就是只能说不能做的"嘴炮"。


一、Function Calling 是什么

1.1 核心概念

关键澄清:模型不直接执行函数。它只是告诉你"我想调哪个函数、传什么参数",实际执行由你的代码完成。

json 复制代码
用户: "北京今天天气怎么样?"
  │
  ▼
┌──────────────────────────────────────────────────────┐
│ 1. 模型收到问题 + 可用工具列表                          │
│ 2. 模型决定:需要调用 get_weather 函数                  │
│ 3. 模型生成:{"name":"get_weather","args":{"city":"北京"}} │
│              (模型到这里就停了,不执行)                  │
└──────────┬───────────────────────────────────────────┘
           │
           ▼
┌──────────────────────────────────────────────────────┐
│ 4. 你的代码执行 get_weather("北京")                     │
│ 5. 得到结果: {"temp": 8, "weather": "晴"}               │
│ 6. 把结果返回给模型                                     │
└──────────┬───────────────────────────────────────────┘
           │
           ▼
┌──────────────────────────────────────────────────────┐
│ 7. 模型基于工具结果生成回答:                            │
│    "北京今天天气晴朗,气温 8°C,适合户外活动。"          │
└──────────────────────────────────────────────────────┘

1.2 与传统 API 调用的区别

维度 传统 API 调用 Function Calling
触发方式 硬编码 if-else 模型自主决策
参数来源 代码中固定/用户表单 模型从自然语言中提取
灵活性 低(预设路径) 高(模型理解意图)
适用场景 结构化输入 自然语言输入

二、三大平台实现对比

2.1 OpenAI

python 复制代码
from openai import OpenAI
import json

client = OpenAI()

# 1. 定义工具
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的当前天气",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名称,如'北京'、'上海'"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "温度单位"
                    }
                },
                "required": ["city"]
            }
        }
    }
]

# 2. 发送请求
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "北京今天天气怎么样?"}],
    tools=tools,
    tool_choice="auto",  # auto: 模型自行决定是否调用工具
)

# 3. 检查是否要调用工具
message = response.choices[0].message
if message.tool_calls:
    for tool_call in message.tool_calls:
        func_name = tool_call.function.name
        func_args = json.loads(tool_call.function.arguments)
        print(f"模型要调用: {func_name}({func_args})")
        
        # 4. 执行函数(你的代码)
        result = get_weather(**func_args)  # 假设你实现了这个函数
        
        # 5. 把结果返回给模型
        messages = [
            {"role": "user", "content": "北京今天天气怎么样?"},
            message,  # 模型的工具调用请求
            {
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result)
            }
        ]
        
        # 6. 模型生成最终回答
        final = client.chat.completions.create(
            model="gpt-4o", messages=messages
        )
        print(final.choices[0].message.content)

2.2 Anthropic Claude

python 复制代码
import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=[
        {
            "name": "get_weather",
            "description": "获取指定城市的当前天气",
            "input_schema": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名称"},
                },
                "required": ["city"]
            }
        }
    ],
    messages=[{"role": "user", "content": "北京今天天气怎么样?"}]
)

# Claude 的工具调用在 content block 中
for block in response.content:
    if block.type == "tool_use":
        print(f"调用: {block.name}({block.input})")

2.3 三大平台对比

特性 OpenAI Anthropic Google Gemini
API 字段 tools tools tools
工具描述 function.parameters input_schema function_declarations
并行调用 支持 支持 支持
流式支持 支持 支持 支持
强制调用 tool_choice: required tool_choice: any tool_config
结果返回 role: "tool" role: "user" + tool_result role: "function"

三、自定义工具开发实战

3.1 工具描述设计原则

工具描述(Tool Schema)的质量直接决定模型能否正确调用。

python 复制代码
# ❌ 差的工具描述
{
    "name": "search",
    "description": "搜索",
    "parameters": {"q": {"type": "string"}}
}

# ✅ 好的工具描述
{
    "name": "search_knowledge_base",
    "description": "在公司内部知识库中搜索信息。适用于查询公司政策、产品文档、技术规范等内部资料。不适用于查询外部网页内容。",
    "parameters": {
        "type": "object",
        "properties": {
            "query": {
                "type": "string",
                "description": "搜索关键词或自然语言问题,如'年假政策'或'产品 A 的技术规格'"
            },
            "category": {
                "type": "string",
                "enum": ["policy", "product", "tech", "all"],
                "description": "搜索范围。policy=公司制度,product=产品文档,tech=技术规范,all=全部"
            },
            "max_results": {
                "type": "integer",
                "description": "返回结果数量,默认5,最大20",
                "default": 5
            }
        },
        "required": ["query"]
    }
}

关键原则

  1. 名称清晰search_knowledge_base >> search
  2. 描述详细 :说明功能、适用场景、不适用场景
  3. 参数描述:每个参数都要有说明和示例
  4. 枚举值:能列举就列举,减少模型的猜测空间

3.2 多工具协同调用示例

python 复制代码
tools = [
    {
        "type": "function",
        "function": {
            "name": "query_database",
            "description": "查询数据库中的销售数据",
            "parameters": {
                "type": "object",
                "properties": {
                    "sql": {"type": "string", "description": "SQL 查询语句"},
                    "database": {"type": "string", "enum": ["sales", "inventory", "customers"]}
                },
                "required": ["sql", "database"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "send_email",
            "description": "发送邮件通知",
            "parameters": {
                "type": "object",
                "properties": {
                    "to": {"type": "string", "description": "收件人邮箱"},
                    "subject": {"type": "string"},
                    "body": {"type": "string"}
                },
                "required": ["to", "subject", "body"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "generate_chart",
            "description": "根据数据生成图表",
            "parameters": {
                "type": "object",
                "properties": {
                    "data": {"type": "string", "description": "JSON 格式的数据"},
                    "chart_type": {"type": "string", "enum": ["bar", "line", "pie"]},
                    "title": {"type": "string"}
                },
                "required": ["data", "chart_type"]
            }
        }
    }
]

# 用户请求:
# "查一下上个月的销售数据,做一个柱状图,然后发邮件给老板"
# 模型会依次调用: query_database → generate_chart → send_email

四、并行调用与多轮交互

4.1 并行调用

模型可以一次返回多个工具调用请求,你可以并行执行:

python 复制代码
# 用户: "查一下北京和上海的天气"
# 模型返回 2 个 tool_calls:
# - get_weather(city="北京")
# - get_weather(city="上海")

import asyncio

async def execute_tools(tool_calls):
    tasks = [execute_single_tool(tc) for tc in tool_calls]
    results = await asyncio.gather(*tasks)  # 并行执行
    return results

4.2 多轮工具调用

有些任务需要多轮工具调用------前一个工具的结果决定下一步调什么:

css 复制代码
用户: "帮我找到销售最好的产品,然后查它的库存"

轮次1: 模型调用 query_database("SELECT TOP 1 product FROM sales ORDER BY amount DESC")
结果: {"product": "产品A", "amount": 1000000}

轮次2: 模型基于上一步结果,调用 query_database("SELECT stock FROM inventory WHERE product='产品A'")
结果: {"product": "产品A", "stock": 523}

轮次3: 模型生成最终回答
"销售最好的是产品A(总销售额100万),当前库存523件。"

五、错误处理与安全考量

5.1 安全检查清单

检查项 做法 重要性
参数校验 模型生成的参数不一定可信,必须校验 🔴 关键
权限控制 不是所有工具都应该暴露给模型 🔴 关键
确认机制 高风险操作(删除、支付)需人类确认 🔴 关键
注入防护 SQL 注入、命令注入 🔴 关键
速率限制 防止模型无限循环调用工具 🟡 重要
超时处理 工具执行超时的降级策略 🟡 重要
日志记录 记录所有工具调用,便于审计 🟡 重要
python 复制代码
# 安全执行框架
def safe_execute_tool(tool_name, args, user_context):
    # 1. 权限检查
    if tool_name not in user_context.allowed_tools:
        return {"error": "无权限调用此工具"}
    
    # 2. 参数校验
    validated_args = validate_args(tool_name, args)
    if not validated_args.is_valid:
        return {"error": f"参数校验失败: {validated_args.errors}"}
    
    # 3. 高风险操作确认
    if is_high_risk(tool_name):
        confirmation = request_human_confirmation(tool_name, args)
        if not confirmation:
            return {"error": "用户取消了操作"}
    
    # 4. 执行并记录
    try:
        result = execute_with_timeout(tool_name, validated_args, timeout=30)
        log_tool_call(tool_name, args, result, user_context)
        return result
    except TimeoutError:
        return {"error": "工具执行超时"}

六、从 Function Calling 到 Agent

Function Calling 是 Agent 的基础构件:

javascript 复制代码
Function Calling(单次工具调用)
    ↓  加上循环
ReAct 模式(推理-行动交替)
    ↓  加上标准化
MCP 协议(统一工具接口)
    ↓  加上自主决策
Agent(自主完成复杂任务)

理解 Function Calling 的工作原理,是学 Agent 开发的前提------Agent 本质上就是在循环中反复做 Function Calling。


七、职业视角

问题 核心答案要点
FC 的工作流程? 用户提问 → 模型选工具+生成参数 → 代码执行 → 结果返回模型 → 最终回答
怎么设计工具描述? 名称清晰、描述详细(含适用/不适用场景)、参数有说明+示例
FC 和 MCP 的关系? FC 是能力(模型决定调什么),MCP 是协议(标准化工具接口)
安全考量? 参数校验、权限控制、高风险确认、注入防护

Function Calling 几乎所有 LLM 应用岗位都会用到------它是连接模型和真实世界的桥梁。


总结

  1. 本质:模型不执行函数,只决定"调什么、传什么",执行由你的代码完成
  2. 三大平台:OpenAI/Anthropic/Google 实现方式类似,核心是工具定义+结果返回
  3. 工具描述是关键:名称清晰、描述详细、参数有约束
  4. 安全第一:参数校验、权限控制、确认机制、日志审计
  5. 通向 Agent:FC → ReAct → MCP → Agent,FC 是基础

本文是 AI 核心技能系列 第 6 篇,共 12 篇。上一篇:RAG 从零到一 | 下一篇:Fine-tuning 实战

关注公众号「coft」,获取完整系列更新、配套代码和学习路线图。一起交流 AI 转行经验,助力职业跃升,迈向高薪岗位。

相关推荐
程序员飞哥2 小时前
Block科技公司裁员四千人,竟然是因为 AI ?
人工智能·后端·程序员
大模型真好玩2 小时前
大模型训练全流程实战指南工具篇(七)——EasyDataset文档处理流程
人工智能·langchain·deepseek
billhan20162 小时前
Embedding 与向量数据库:语义理解的基础设施
人工智能
OpenBayes贝式计算2 小时前
解决视频模型痛点,TurboDiffusion 高效视频扩散生成系统;Google Streetview 涵盖多个国家的街景图像数据集
人工智能·深度学习·机器学习
OpenBayes贝式计算2 小时前
OCR教程汇总丨DeepSeek/百度飞桨/华中科大等开源创新技术,实现OCR高精度、本地化部署
人工智能·深度学习·机器学习
我要改名叫嘟嘟3 小时前
年后上班三天之后,忽然想作的一次记录
人工智能·程序员
飞哥数智坊3 小时前
SWE-bench 退役:当 AI 评测沦为“刷题游戏”,我们还能信谁?
人工智能
爱可生开源社区4 小时前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
AI布道官5 小时前
手把手安装教程(2026最新版)
人工智能