ANALYSIS
概述
Function Calling(函数调用)是一种让 LLM 主动调用预定义函数的能力。模型可以根据对话上下文,判断何时需要调用哪个函数,并从外部获取执行结果。
如果说普通 LLM 是一个”会说话的大脑”,那么 Function Calling 让它拥有了”动手能力”——可以查询实时数据、执行代码、操作文件,真正从被动回答走向主动行动。
为什么需要 Function Calling
LLM 的能力边界
| 能力 | 纯 LLM | Function Calling |
|---|---|---|
| 知识问答 | ✅ | ✅ |
| 实时信息 | ❌ | ✅ |
| 数值计算 | ⚠️ 不精确 | ✅ 精确 |
| 文件操作 | ❌ | ✅ |
| API 调用 | ❌ | ✅ |
| 任务执行 | ❌ | ✅ |
核心价值
| 痛点 | 解决方案 |
|---|---|
| 模型不知道实时信息 | 通过 API 函数查询最新数据 |
| 模型无法执行操作 | 调用代码执行函数完成任务 |
| 上下文信息不足 | 通过搜索 / 数据库函数获取补充 |
| 缺乏行动能力 | 函数调用实现任务闭环 |
工作原理详解
完整调用流程
PRTCL // PLAINTEXT
┌──────────────────────────────────────────────────────────────┐│ Function Calling 完整流程 │├──────────────────────────────────────────────────────────────┤│ ││ 用户:"帮我查一下成都明天的天气,然后发邮件告诉张三 ││ ││ Step 1: 模型分析意图 ││ ┌──────────────────────────────────────────┐ ││ │ 需要两步操作: │ ││ │ 1. 查询天气(get_weather) │ ││ │ 2. 发送邮件(send_email) │ ││ └──────────────────────────────────────────┘ ││ ↓ ││ Step 2: 输出函数调用 ││ ┌──────────────────────────────────────────┐ ││ │ { │ ││ │ "name": "get_weather", │ ││ │ "arguments": {"city": "成都", │ ││ │ "date": "明天"} │ ││ │ } │ ││ └──────────────────────────────────────────┘ ││ ↓ ││ Step 3: 后端执行函数 ││ ┌──────────────────────────────────────────┐ ││ │ get_weather("成都", "明天") │ ││ │ → {"temperature": 22, "condition": "晴"} │ ││ └──────────────────────────────────────────┘ ││ ↓ ││ Step 4: 函数结果注入上下文 ││ ┌──────────────────────────────────────────┐ ││ │ 天气查询结果:22°C,晴 │ ││ │ 现在调用 send_email... │ ││ └──────────────────────────────────────────┘ ││ ↓ ││ Step 5: 模型生成回复 ││ "成都明天天气晴朗,气温 22°C。我已经帮您发邮件告知张三了。" ││ │└──────────────────────────────────────────────────────────────┘模型如何决定调用
模型通过分析用户意图来判断是否需要调用函数:
PRTCL // PLAINTEXT
用户输入 → 意图识别 → 是否需要外部操作? → 是 / 否 ↓ 选择合适的函数 → 输出调用请求函数定义规范
JSON Schema 定义
PRTCL // JSON
{ "name": "get_weather", "description": "获取指定城市和日期的天气信息", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,支持中文或拼音" }, "date": { "type": "string", "description": "日期,格式为 YYYY-MM-DD 或 ' 今天 '/' 明天 '/' 后天 '" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "温度单位,默认 celsius" } }, "required": ["city", "date"] }}描述编写技巧
| 要素 | 说明 | 示例 |
|---|---|---|
| 函数名 | 动词开头,清晰明确 | get_weather, search_files |
| 整体描述 | 说明函数做什么 | ”获取指定城市和日期的天气” |
| 参数描述 | 说明每个参数的含义和格式 | ”城市名称,中文或拼音” |
| 返回值说明 | 说明返回什么 | ”返回温度、天气状况等” |
参数设计原则
| 原则 | 说明 | 示例 |
|---|---|---|
| 必选参数用 required | 明确标记 | ”required”: [“city”, “date”] |
| 参数类型要精确 | 减少歧义 | ”type”: “string”, “enum”: […] |
| 描述要清晰 | 帮助模型理解 | ”description”: ”…” |
| 有默认值用 default | 简化调用 | ”default”: “celsius” |
使用场景详解
天气查询
PRTCL // PYTHON
# 定义工具tools = [ { "name": "get_weather", "description": "获取城市天气", "parameters": { "type": "object", "properties": { "city": {"type": "string"}, "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]} }, "required": ["city"] } }, { "name": "get_forecast", "description": "获取多天天气预报", "parameters": { "type": "object", "properties": { "city": {"type": "string"}, "days": {"type": "integer", "minimum": 1, "maximum": 7} }, "required": ["city"] } }]日历管理
PRTCL // PYTHON
tools = [ { "name": "create_event", "description": "创建日历事件", "parameters": { "type": "object", "properties": { "title": {"type": "string", "description": "事件标题"}, "datetime": {"type": "string", "description": "ISO 8601 格式"}, "duration": {"type": "integer", "description": "持续时间(分钟)"}, "attendees": {"type": "array", "items": {"type": "string"}} }, "required": ["title", "datetime"] } }, { "name": "get_events", "description": "查询日历事件", "parameters": { "type": "object", "properties": { "start_date": {"type": "string"}, "end_date": {"type": "string"} } } }]发送消息
PRTCL // PYTHON
tools = [ { "name": "send_email", "description": "发送邮件", "parameters": { "type": "object", "properties": { "to": {"type": "string", "description": "收件人邮箱"}, "subject": {"type": "string"}, "body": {"type": "string"}, "cc": {"type": "array", "items": {"type": "string"}} }, "required": ["to", "subject", "body"] } }, { "name": "send_slack", "description": "发送 Slack 消息", "parameters": { "type": "object", "properties": { "channel": {"type": "string"}, "message": {"type": "string"} }, "required": ["channel", "message"] } }]数据库查询
PRTCL // PYTHON
tools = [ { "name": "query_sql", "description": "执行 SQL 查询", "parameters": { "type": "object", "properties": { "sql": { "type": "string", "description": "SQL 查询语句,只支持 SELECT" } }, "required": ["sql"] } }]
# 使用示例# "查一下上个月销售额最高的产品"# → query_sql("SELECT product_name, SUM(amount) as total FROM sales WHERE date >= '2026-02-01' GROUP BY product_name ORDER BY total DESC LIMIT 5")代码执行
PRTCL // PYTHON
tools = [ { "name": "run_python", "description": "执行 Python 代码", "parameters": { "type": "object", "properties": { "code": {"type": "string"}, "timeout": {"type": "integer", "default": 30} }, "required": ["code"] } }, { "name": "run_shell", "description": "执行 Shell 命令", "parameters": { "type": "object", "properties": { "command": {"type": "string"} }, "required": ["command"] } }]文件操作
PRTCL // PYTHON
tools = [ { "name": "read_file", "description": "读取文件内容", "parameters": { "type": "object", "properties": { "path": {"type": "string"}, "encoding": {"type": "string", "default": "utf-8"} }, "required": ["path"] } }, { "name": "write_file", "description": "写入文件", "parameters": { "type": "object", "properties": { "path": {"type": "string"}, "content": {"type": "string"} }, "required": ["path", "content"] } }, { "name": "list_directory", "description": "列出目录内容", "parameters": { "type": "object", "properties": { "path": {"type": "string"}, "recursive": {"type": "boolean", "default": false} }, "required": ["path"] } }]主流模型支持
| 模型 | 支持程度 | 稳定性 | 特点 |
|---|---|---|---|
| GPT-4 / GPT-3.5 | ✅ 完全支持 | 高 | 成熟稳定,生态完善 |
| Claude 3+ | ✅ 完全支持 | 高 | JSON 输出能力强 |
| 通义千问 | ✅ 支持 | 高 | 中文优化 |
| GLM-4 | ✅ 支持 | 高 | 国产主流 |
| DeepSeek | ✅ 支持 | 高 | 性价比高 |
| Llama(本地) | ⚠️ 部分 | 中 | 需配置 |
最佳实践
函数设计原则
| 原则 | 说明 | 示例 |
|---|---|---|
| 职责单一 | 每个函数只做一件事 | get_weather ❌, get_weather+get_forecast ✅ |
| 参数简洁 | 避免过多参数 | 最多 7-8 个参数 |
| 类型明确 | 减少歧义 | 用 enum 限制选项 |
| 描述清晰 | 帮助模型理解 | description 要详细 |
错误处理
PRTCL // PYTHON
def execute_function(name: str, arguments: dict) -> dict: try: # 验证参数 validate_arguments(name, arguments)
# 执行函数 result = call_function(name, arguments)
return { "success": True, "data": result }
except ValidationError as e: return { "success": False, "error": f"参数错误: {e.message}" } except ExecutionError as e: return { "success": False, "error": f"执行失败: {e.message}" } except PermissionError as e: return { "success": False, "error": f"权限不足: {e.message}" } except Exception as e: return { "success": False, "error": f"未知错误: {e}" }安全考虑
| 风险 | 防护措施 |
|---|---|
| SQL 注入 | 只支持 SELECT,禁止 DDL/DML |
| 命令注入 | 白名单限制可用命令 |
| 文件操作 | 限制路径范围 |
| API 调用 | 权限控制和频率限制 |
| 数据泄露 | 敏感数据脱敏 |
Function Calling vs MCP
| 维度 | Function Calling | MCP |
|---|---|---|
| 标准化 | 各平台自定义 | 统一协议 |
| 范围 | 单应用内函数 | 多应用间互联 |
| 灵活性 | 高 | 中 |
| 生态 | 封闭 | 开放 |
| 开发成本 | 每个应用独立开发 | 一次实现,生态通用 |
两者结合使用: MCP 服务器可以作为 Function Calling 的实现后端,兼顾灵活性和生态性。
总结
Function Calling 是让 AI 从”被动回答”走向”主动行动”的关键能力。通过合理设计函数,可以让 AI 自动完成查询、计算、文件操作等各种任务,大幅提升 AI 应用的实用性和自动化水平。
关于我
| 项目 | 内容 |
|---|---|
| 编辑 | echowang |
| 来源 | echospace |
| 邮箱 | echohaoran@gmail.com |
| 简介 | AI 爱好者,专注于大语言模型应用与智能体开发,分享技术与实践心得 |
| 社交 | 欢迎交流讨论,共同成长 |
R P
Rhine Lab Pioneer Division
Auth_Verified: 2026.03.21
Auth_Verified: 2026.03.21
