AI Skills 与 Function Calling 指南
2026年1月更新Tool UseFunction Calling(函数调用) 是让 LLM 从"对话助手"进化为"行动执行者"的关键能力。它使 AI 能够调用外部工具、API 和服务,突破模型自身的知识边界。本指南基于 Anthropic Engineering 系列技术文章整理。
一、核心概念
1.1 什么是工具?
传统软件编程中,我们在确定性系统之间建立契约:给定相同输入,getWeather("北京") 每次都会以完全相同的方式获取北京的天气。
工具(Tool) 是一种新型软件,反映的是确定性系统与非确定性 Agent 之间的契约:
| 传统 API 调用 | Agent 工具调用 |
|---|---|
| 开发者明确指定调用什么、何时调用 | Agent 自主决定是否调用、调用哪个 |
| 输入参数由代码确定 | 参数从自然语言推断 |
| 输出直接使用 | 输出需要 Agent 解读并决定下一步 |
重新思考工具设计
为 Agent 编写工具不同于为开发者编写 API。最适合 Agent 使用的工具,往往对人类来说也更直观易懂。
1.2 术语对照
| 术语 | 说明 |
|---|---|
| AI Skill | AI 能够执行的特定能力或操作 |
| Function Calling | LLM 生成结构化输出来调用外部函数 |
| Tool Calling / Tool Use | 同 Function Calling,更通用的称呼 |
| ACI | Agent-Computer Interface,代理-计算机接口 |
1.3 为什么需要 Function Calling?
LLM 的局限性:
├── 知识截止日期(无法获取实时信息)
├── 无法执行计算(数学运算不可靠)
├── 无法访问外部系统(数据库、API)
└── 无法执行操作(发邮件、创建文件)
↓ Function Calling 解决
AI 能够:
├── 调用天气 API 获取实时天气
├── 执行 Python 代码进行精确计算
├── 查询数据库获取业务数据
└── 调用服务执行实际操作二、工作原理
2.1 基本流程
用户输入
↓
LLM 分析意图
↓
生成函数调用(JSON 格式)
↓
应用程序执行函数
↓
将结果返回给 LLM
↓
LLM 生成最终回复2.2 详细示例
用户输入: "北京今天天气怎么样?"
// Step 1: LLM 生成函数调用
{
"function": "get_weather",
"arguments": {
"city": "北京",
"date": "2025-12-31"
}
}
// Step 2: 应用程序执行函数,获取结果
{
"temperature": "5°C",
"condition": "晴",
"humidity": "30%"
}
// Step 3: LLM 基于结果生成回复
"北京今天天气晴朗,气温5°C,湿度30%,适合外出活动。"2.3 关键要点
| 要点 | 说明 |
|---|---|
| LLM 不执行函数 | LLM 只生成调用指令,实际执行由应用程序完成 |
| 结构化输出 | 通常使用 JSON 格式传递函数名和参数 |
| 多轮交互 | 可能需要多次函数调用完成复杂任务 |
| 并行调用 | 部分平台支持同时调用多个函数 |
三、ACI:代理-计算机接口
3.1 什么是 ACI?
Anthropic 提出 ACI(Agent-Computer Interface) 的概念:
设计工具时应投入与 HCI(人机接口) 同等的精力。
工具定义和规范会被加载到 Agent 的上下文中,它们可以集体引导 Agent 采取正确的工具调用行为。
3.2 设计原则
| 原则 | 说明 |
|---|---|
| 换位思考 | 把自己放在模型的位置:仅凭描述和参数,用法是否显而易见? |
| 像写文档一样 | 想象为团队中的新人写一份清晰的 docstring |
| 迭代测试 | 在 Workbench 中运行多种输入,观察模型的错误,持续改进 |
| 防呆设计(Poka-yoke) | 修改参数设计,使犯错变得更难 |
实践经验
在构建 SWE-bench Agent 时,Anthropic 团队表示"在优化工具上花的时间比优化整体提示更多"。例如,发现模型使用相对路径会出错后,他们将工具改为始终要求绝对路径,模型就能完美使用了。
四、工具设计最佳实践
4.1 选择正确的工具
更多工具不等于更好效果。常见错误是简单包装现有 API,而没有考虑这些工具是否适合 Agent。
| 传统软件 | Agent |
|---|---|
| 计算机内存便宜充裕 | 上下文窗口有限且昂贵 |
| 可以逐一遍历大列表 | 浪费宝贵的上下文空间 |
示例对比:
| ❌ 不推荐 | ✅ 推荐 |
|---|---|
list_contacts → 返回所有联系人 | search_contacts → 按关键词搜索 |
list_users + list_events + create_event | schedule_event → 一站式完成 |
read_logs → 返回全部日志 | search_logs → 返回相关行及上下文 |
get_customer_by_id + list_transactions + list_notes | get_customer_context → 一次性获取所有相关信息 |
4.2 整合功能
工具可以在后台处理多个离散操作或 API 调用:
// ❌ 分散的工具
["list_users", "list_events", "create_event"]
// ✅ 整合的工具
{
"name": "schedule_event",
"description": "查找参与者的空闲时间并安排会议,自动发送日历邀请"
}4.3 命名空间
当工具数量增多时,使用命名空间帮助 Agent 区分:
| 策略 | 示例 |
|---|---|
| 按服务分 | asana_search, jira_search |
| 按资源分 | asana_projects_search, asana_users_search |
注意
前缀式和后缀式命名对不同 LLM 可能有不同效果,建议通过评估选择最佳方案。
4.4 返回有意义的上下文
工具返回应优先包含高信号信息:
| ❌ 低信号 | ✅ 高信号 |
|---|---|
uuid, 256px_image_url, mime_type | name, image_url, file_type |
| 神秘的字母数字 UUID | 语义化、可解释的标识符 |
支持多种响应格式:
enum ResponseFormat {
DETAILED = "detailed", // 完整信息,用于最终输出
CONCISE = "concise" // 精简信息,用于中间步骤
}4.5 Token 效率优化
| 策略 | 说明 |
|---|---|
| 分页 | 大数据集分批返回 |
| 范围选择 | 允许指定数据范围 |
| 过滤 | 支持条件过滤 |
| 截断 | 设置合理的默认上限(如 Claude Code 默认 25,000 tokens) |
错误信息也要优化:
| ❌ 不友好 | ✅ 友好 |
|---|---|
Error: 400 Bad Request | 需要指定 user_id 参数。提示:可以先调用 search_users 获取用户 ID |
| 完整的堆栈跟踪 | 具体、可操作的改进建议 |
五、工具定义规范
5.1 良好示例
{
"name": "search_products",
"description": "在商品数据库中搜索产品。当用户询问商品信息、价格或库存时使用此函数。返回:产品列表,每项包含 id(字符串)、name(字符串)、price(浮点数,人民币)、in_stock(布尔值)。",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词,如产品名称或类别"
},
"category": {
"type": "string",
"enum": ["electronics", "clothing", "food", "books"],
"description": "产品类别,用于缩小搜索范围"
},
"max_price": {
"type": "number",
"description": "最高价格限制(人民币)"
},
"in_stock": {
"type": "boolean",
"description": "是否只显示有库存的商品,默认 true"
}
},
"required": ["query"]
}
}5.2 工具定义规范
| 元素 | 建议 |
|---|---|
| 函数名 | 使用动词开头(search_、create_、update_),避免模糊命名如 query_db |
| 描述 | 清晰说明用途、使用场景、返回值格式 |
| 参数名 | 明确具体,用 user_id 而非 user |
| 必填项 | 明确标注 required |
| 枚举值 | 有限选项使用 enum 约束 |
| 格式说明 | 日期格式、ID 格式等要明确指定 |
5.3 使用工具示例(Tool Use Examples)
JSON Schema 擅长定义结构,但无法表达使用模式。通过提供具体示例,让模型学习:
{
"name": "create_ticket",
"input_schema": { /* schema */ },
"input_examples": [
{
"title": "登录页面返回 500 错误",
"priority": "critical",
"labels": ["bug", "authentication", "production"],
"reporter": {
"id": "USR-12345",
"name": "张三",
"contact": { "email": "zhangsan@example.com" }
},
"due_date": "2025-12-31",
"escalation": { "level": 2, "notify_manager": true, "sla_hours": 4 }
},
{
"title": "添加深色模式支持",
"labels": ["feature-request", "ui"],
"reporter": { "id": "USR-67890", "name": "李四" }
},
{
"title": "更新 API 文档"
}
]
}从这三个示例中,模型学习到:
- 格式约定:日期用
YYYY-MM-DD,用户 ID 格式为USR-XXXXX - 嵌套结构用法:如何构造 reporter 对象
- 可选参数关联:关键 Bug 需要完整信息;功能请求只需基本信息;内部任务只需标题
内部测试结果
Anthropic 内部测试显示,工具使用示例将复杂参数处理的准确率从 72% 提升到 90%。
六、高级工具使用功能
6.1 Tool Search Tool(工具搜索工具)
问题:随着 MCP 服务器增多,工具定义 Token 激增:
- 5 个服务器、58 个工具 → ~55K tokens
- 加上 Jira 等 → 100K+ tokens 在对话开始前就已消耗
解决方案:按需发现工具,而非预加载所有定义:
| 传统方式 | Tool Search Tool |
|---|---|
| 加载所有工具(~72K tokens) | 只加载搜索工具(~500 tokens) |
| 对话开始前消耗 ~77K tokens | 按需加载 3-5 个相关工具(~3K tokens) |
| — | 节省 85% Token |
实现方式:
{
"tools": [
{"type": "tool_search_tool_regex_20251119", "name": "tool_search_tool"},
{
"name": "github.createPullRequest",
"description": "创建 Pull Request",
"input_schema": {...},
"defer_loading": true // 标记为按需加载
}
]
}6.2 Programmatic Tool Calling(程序化工具调用)
问题:传统方式下,每个工具结果都返回 LLM 上下文,处理 20 人的费用报销需要 2000+ 行数据进入上下文。
解决方案:让 Claude 编写代码编排工具调用,中间结果由代码处理,只有最终结果进入上下文:
# Claude 生成的编排代码
team = await get_team_members("engineering")
# 并行获取所有人的费用
expenses = await asyncio.gather(*[
get_expenses(m["id"], "Q3") for m in team
])
# 在代码中处理,只输出超支的人
exceeded = []
for member, exp in zip(team, expenses):
total = sum(e["amount"] for e in exp)
if total > budget_limit:
exceeded.append({"name": member["name"], "spent": total})
print(json.dumps(exceeded)) # 只有这个进入 Claude 的上下文| 传统方式 | Programmatic Tool Calling |
|---|---|
| 2000+ 费用行项(50KB+)进入上下文 | 只有 2-3 个超支人员(1KB)进入上下文 |
| 平均 43,588 tokens | 平均 27,297 tokens(减少 37%) |
6.3 何时使用这些功能
| 功能 | 适用场景 |
|---|---|
| Tool Search Tool | 工具定义 >10K tokens;工具 >10 个;MCP 多服务器 |
| Programmatic Tool Calling | 大量中间结果污染上下文;需要并行执行的独立操作 |
| Tool Use Examples | 参数格式不明确;复杂嵌套结构;可选参数使用模式 |
七、主流平台支持
7.1 平台对比
| 平台 | 特性 | 并行调用 | JSON Mode | 高级功能 |
|---|---|---|---|---|
| Anthropic | Tool Use + MCP | ✓ | ✓ | Tool Search, PTC, Examples |
| OpenAI | 成熟稳定 | ✓ | ✓ | Parallel Function Calling |
| Gemini Function Calling | ✓ | ✓ | — | |
| Mistral | 原生支持 | ✓ | ✓ | — |
7.2 Anthropic Tool Use 示例
import anthropic
client = anthropic.Anthropic()
tools = [
{
"name": "get_weather",
"description": "获取指定城市的当前天气。返回:temperature(字符串),condition(字符串),humidity(字符串)",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如'北京'、'上海'"
}
},
"required": ["city"]
}
}
]
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "北京今天天气如何?"}]
)
# 处理工具调用
for block in response.content:
if block.type == "tool_use":
tool_name = block.name
tool_input = block.input
# 执行工具并返回结果...7.3 OpenAI Function Calling 示例
import openai
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如 北京、上海"
}
},
"required": ["city"]
}
}
}
]
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "北京天气如何?"}],
tools=tools,
tool_choice="auto"
)
if response.choices[0].message.tool_calls:
tool_call = response.choices[0].message.tool_calls[0]
# 执行函数并获取结果...八、评估与测试
8.1 评估驱动的工具开发
Anthropic 推荐评估驱动的工具开发流程:
1. 构建原型 → 快速实现工具
↓
2. 生成评估任务 → 基于真实场景
↓
3. 运行评估 → 测量工具使用效果
↓
4. 分析结果 → 与 Agent 协作发现问题
↓
5. 改进工具 → 迭代优化8.2 强评估任务 vs 弱评估任务
| ✅ 强评估任务 | ❌ 弱评估任务 |
|---|---|
| "安排下周与 Jane 的会议讨论 Acme 项目,附上上次会议笔记,预订会议室" | "安排与 jane@acme.corp 的会议" |
| "客户 ID 9182 反映被重复收费三次,找出所有相关日志,确定是否有其他客户受影响" | "搜索 purchase_complete 和 customer_id=9182 的日志" |
| "客户 Sarah Chen 提交了取消请求,准备挽留方案:分析离开原因、最有吸引力的挽留offer、风险因素" | "查找客户 ID 45892 的取消请求" |
8.3 评估指标
| 指标 | 说明 |
|---|---|
| 工具选择准确率 | 是否选择了正确的工具 |
| 参数提取准确率 | 参数值是否正确提取 |
| 调用成功率 | 工具调用是否成功执行 |
| 端到端成功率 | 整体任务完成率 |
| Token 消耗 | 评估效率 |
| 工具调用次数 | 揭示常见工作流 |
8.4 测试工具
| 工具 | 说明 |
|---|---|
| Anthropic Workbench | 在线测试工具调用 |
| BFCL | Berkeley Function Calling Leaderboard |
| Tool Evaluation Cookbook | Anthropic 官方评估指南 |
九、进阶模式
9.1 多工具编排
任务:预订从北京到上海的航班和酒店
Agent 工作流:
1. search_flights(from="北京", to="上海", date="2025-01-15")
2. get_flight_details(flight_id="...")
3. search_hotels(city="上海", check_in="2025-01-15")
4. compare_prices(items=[...])
5. create_booking(...)9.2 并行调用
# 同时获取多个信息
tools_calls = [
{"function": "get_weather", "arguments": {"city": "北京"}},
{"function": "get_weather", "arguments": {"city": "上海"}},
{"function": "get_news", "arguments": {"topic": "科技"}}
]9.3 Think 工具配合
在复杂工具调用场景中,可以使用 Think 工具 让 Agent 在调用前停下来思考:
{
"name": "think",
"description": "用于思考。不会执行任何操作,仅记录思考过程。当需要分析工具输出或规划下一步时使用。",
"input_schema": {
"type": "object",
"properties": {
"thought": { "type": "string", "description": "思考内容" }
},
"required": ["thought"]
}
}十、安全与权限
10.1 安全考虑
| 风险 | 缓解措施 |
|---|---|
| 过度权限 | 最小权限原则,只授予必要权限 |
| 注入攻击 | 参数验证和清洗 |
| 敏感操作 | 高风险操作需人工确认 |
| 数据泄露 | 日志脱敏,访问控制 |
10.2 MCP 工具注解
MCP 协议支持工具注解,声明工具的安全属性:
{
"name": "delete_file",
"annotations": {
"destructive": true,
"requires_confirmation": true
}
}10.3 权限模型
用户操作
↓
权限检查(用户级别、操作类型)
↓
函数白名单验证
↓
参数合法性检查
↓
执行(可能需人工确认)
↓
审计日志记录十一、最佳实践总结
✅ 推荐做法
| 实践 | 说明 |
|---|---|
| 精简工具集 | 针对高影响力工作流构建少量精心设计的工具 |
| 清晰的描述 | 包含用途、场景、返回格式 |
| 具体的参数名 | 用 user_id 而非 user |
| 返回高信号信息 | 优先自然语言名称而非技术标识符 |
| 支持响应格式切换 | 简洁/详细模式 |
| 提供使用示例 | 消除格式和用法歧义 |
| Token 效率 | 分页、过滤、截断 |
| 友好的错误信息 | 具体、可操作的改进建议 |
⚠️ 避免事项
| 事项 | 说明 |
|---|---|
| 工具过多 | 增加选择错误概率,分散 Agent 注意力 |
| 简单包装 API | 没有考虑 Agent 的使用方式 |
| 模糊的描述 | 导致错误调用 |
| 返回全部数据 | 浪费宝贵的上下文空间 |
| 技术性 ID | 神秘的 UUID 容易导致幻觉 |
| 忽略错误处理 | 应提供清晰的错误信息 |
十二、Antigravity Agent Skills
12.1 什么是 Skills?
Skills 是一种扩展 Agent 能力的开放标准。一个 Skill 就是一个文件夹,包含 SKILL.md 文件,其中有 Agent 在处理特定任务时可以遵循的指令。
Skills 是可复用的知识包,每个 Skill 包含:
| 组成部分 | 说明 |
|---|---|
| 任务指令 | 如何处理特定类型任务的方法 |
| 最佳实践 | 应遵循的约定和规范 |
| 脚本资源 | 可选的辅助脚本和资源 |
当你开始对话时,Agent 会看到可用 Skills 的列表及其名称和描述。如果某个 Skill 与你的任务相关,Agent 会读取完整指令并遵循它们。
12.2 Skills 存放位置
Antigravity 支持两种类型的 Skills:
| 位置 | 作用范围 |
|---|---|
<workspace-root>/.agent/skills/<skill-folder>/ | 工作区专用 |
~/.gemini/antigravity/skills/<skill-folder>/ | 全局(所有工作区) |
工作区 Skills 适合项目专用的工作流,如团队的部署流程或测试约定。
全局 Skills 跨所有项目生效,适合个人工具或通用工具。
12.3 创建 Skill
创建 Skill 的步骤:
- 在 Skills 目录中创建一个文件夹
- 在文件夹内添加
SKILL.md文件
.agent/skills/
└─── my-skill/
└─── SKILL.md每个 Skill 都需要一个带有 YAML frontmatter 的 SKILL.md 文件:
---
name: my-skill
description: Helps with a specific task. Use when you need to do X or Y.
---
# My Skill
Detailed instructions for the agent go here.
## When to use this skill
- Use this when...
- This is helpful for...
## How to use it
Step-by-step guidance, conventions, and patterns the agent should follow.12.4 Frontmatter 字段
| 字段 | 必填 | 说明 |
|---|---|---|
name | 否 | Skill 的唯一标识符(小写,用连字符分隔)。如未提供,默认使用文件夹名 |
description | 是 | 清晰描述 Skill 的功能和使用场景。这是 Agent 决定是否应用该 Skill 的依据 |
描述技巧
使用第三人称编写描述,并包含帮助 Agent 识别相关性的关键词。例如:"Generates unit tests for Python code using pytest conventions."
12.5 Skill 文件夹结构
虽然 SKILL.md 是唯一必需的文件,但你可以包含额外资源:
.agent/skills/my-skill/
├─── SKILL.md # 主指令文件(必需)
├─── scripts/ # 辅助脚本(可选)
├─── examples/ # 参考实现(可选)
└─── resources/ # 模板和其他资源(可选)Agent 在遵循 Skill 指令时可以读取这些文件。
12.6 Agent 使用 Skills 的流程
Skills 遵循**渐进式披露(Progressive Disclosure)**模式:
1. 发现(Discovery)
└─ 对话开始时,Agent 看到可用 Skills 的名称和描述列表
↓
2. 激活(Activation)
└─ 如果某个 Skill 与任务相关,Agent 读取完整的 SKILL.md 内容
↓
3. 执行(Execution)
└─ Agent 在处理任务时遵循 Skill 的指令你无需明确告诉 Agent 使用哪个 Skill——它会根据上下文自行决定。但如果你想确保使用某个 Skill,可以在对话中提及它的名称。
12.7 Skills 最佳实践
保持 Skills 专注
每个 Skill 应该专注做好一件事。与其创建一个"万能" Skill,不如为不同任务创建独立的 Skills。
编写清晰的描述
描述是 Agent 决定是否使用 Skill 的依据。要明确说明 Skill 的功能和适用场景。
将脚本作为黑盒使用
如果 Skill 包含脚本,建议 Agent 先用 --help 运行它们,而不是阅读整个源代码。这能让 Agent 的上下文专注于任务本身。
包含决策树
对于复杂的 Skills,添加一个帮助 Agent 根据情况选择正确方法的章节。
12.8 Skill 示例:代码审查
这是一个帮助 Agent 审查代码的简单 Skill:
---
name: code-review
description: Reviews code changes for bugs, style issues, and best practices. Use when reviewing PRs or checking code quality.
---
# Code Review Skill
When reviewing code, follow these steps:
## Review checklist
1. **Correctness**: Does the code do what it's supposed to?
2. **Edge cases**: Are error conditions handled?
3. **Style**: Does it follow project conventions?
4. **Performance**: Are there obvious inefficiencies?
## How to provide feedback
- Be specific about what needs to change
- Explain why, not just what
- Suggest alternatives when possible12.9 Skills vs Tools 对比
| 维度 | Skills | Tools / Function Calling |
|---|---|---|
| 本质 | 知识/指令包 | 可执行的函数接口 |
| 触发方式 | Agent 根据上下文自动识别 | Agent 主动调用 |
| 执行者 | Agent 遵循指令执行 | 外部系统执行函数 |
| 定义位置 | SKILL.md 文件 | JSON Schema |
| 复杂度 | 可包含复杂工作流 | 通常是原子操作 |
| 适用场景 | 流程、规范、方法论 | API 调用、数据获取、操作执行 |
互补关系
Skills 和 Tools 是互补的。Skills 定义"如何做",Tools 提供"用什么做"。一个 Skill 可以指导 Agent 何时以及如何使用特定的 Tools。
📚 推荐阅读
- Writing effective tools for agents — 工具设计最佳实践
- Introducing advanced tool use — 高级工具使用功能
- Building effective agents — Agent 架构与工具使用(Appendix 2)
- Tool Evaluation Cookbook — 工具评估实践指南
- Google Antigravity Skills — Antigravity Agent Skills 官方文档
更多文章参见 Anthropic Engineering 文章合集。