你好,我是这篇教程的作者。在日常开发中,我经常需要让 AI 调用外部工具来完成任务,比如查天气、搜航班、写文件。之前用传统方法实现这些功能特别麻烦,直到我发现 Claude 3.5 的 Function Calling 功能——它让 AI 自动选择调用哪个工具变得超级简单。今天我就手把手教你在 立即注册 HolySheep AI 后,如何从零开始掌握这个强大功能。
一、什么是 Function Calling?为什么你需要它?
想象你走进一家餐厅,服务员(Claude)会主动问你:“请问需要点什么?”但如果菜单是英文的,你可能看不懂。Function Calling 就像是给 Claude 配备了一个“万能翻译官”,它能理解你的需求后,自动帮你执行具体操作。
普通对话模式:Claude 只能回复文字,无法实际操作
Function Calling 模式:Claude 理解你的意图后,会自动调用你写好的函数来完成真实任务
举个实际例子:你想查询明天北京的天气
- ❌ 普通模式:Claude 只能告诉你“请查询天气预报”
- ✅ Function Calling 模式:Claude 自动调用 get_weather 函数,直接返回“北京明天晴,25°C”
二、什么是 JSON Schema?为什么它很重要?
JSON Schema 就像一份“规格说明书”,告诉 Claude 返回的数据应该长什么样。比如你希望天气信息包含“城市名、温度、天气状况”三个字段,JSON Schema 就会明确规定这个结构。
为什么必须用 JSON Schema?
- 确保返回的数据格式固定,你的程序才能正常解析
- 避免 Claude 返回乱七八糟的格式导致程序崩溃
- 方便团队协作,大家都知道数据长什么样
三、为什么选择 HolySheep AI 运行 Claude 3.5?
作为国内开发者,我之前用过官方 API,遇到了三个痛点:
- 💰 价格太贵:Claude 3.5 Sonnet 官方价格 $15/MTok,调用一次成本高
- 🌐 网络延迟:海外服务器动不动 200-500ms,体验很差
- 💳 充值麻烦:需要信用卡,国内开发者很不方便
HolyShehe AI 完美解决了这些问题:
- ✅ 汇率优势:¥1=$1 无损兑换(官方 ¥7.3=$1),节省超过 85% 成本
- ✅ 国内直连:延迟低于 50ms,响应速度飞快
- ✅ 充值便捷:支持微信、支付宝直接充值
- ✅ 注册福利:新用户赠送免费调用额度
2026 年主流模型输出价格参考:Claude Sonnet 4.5 在 HolySheep 上仅需 $15/MTok,配合 ¥1=$1 汇率,性价比极高。
四、环境准备:从注册到 API Key 获取
第一步:注册 HolySheep 账号
(图示:打开 https://www.holysheep.ai/register 页面,填写邮箱和密码)
1. 点击注册链接进入 注册页面
2. 填写邮箱地址、设置密码
3. 使用微信或支付宝完成身份验证
4. 验证通过后进入控制台
第二步:获取 API Key
(图示:控制台左侧菜单找到"API Keys",点击"创建新密钥")
1. 登录后在左侧菜单点击【API Keys】
2. 点击【创建新密钥】按钮
3. 输入密钥名称(可以写“天气查询工具”)
4. 点击确认,系统会生成一串密钥
⚠️ 重要提示:API Key 只显示一次,请立即复制保存到本地记事本
第三步:安装 Python 环境
(图示:命令行输入 python --version 显示 3.9 或更高版本)
# Windows 用户打开 PowerShell,Mac 用户打开 Terminal
检查 Python 版本(需要 3.7 以上)
python --version
安装 requests 库(用于发送 API 请求)
pip install requests
五、Function Calling 实战:天气查询机器人
现在让我们开始写代码!我会一步步教你实现一个天气查询机器人。
5.1 定义工具函数
首先,我们定义一个简单的天气查询“伪函数”(实际由 Claude 决定何时调用):
# weather_bot.py
import requests
定义可用工具列表
tools = [
{
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,例如:北京、上海、东京"
},
"date": {
"type": "string",
"description": "查询日期,格式为 YYYY-MM-DD,例如:2026-01-15"
}
},
"required": ["city", "date"]
}
}
]
def call_get_weather(city: str, date: str):
"""
模拟天气查询函数(实际项目中这里会调用真实天气API)
"""
# 这里用字典模拟天气数据
weather_data = {
"北京": {"晴": 25, "多云": 23, "雨": 18},
"上海": {"晴": 28, "多云": 26, "雨": 22},
"东京": {"晴": 26, "多云": 24, "雨": 20}
}
# 简化处理:随机返回一种天气
import random
city_weather = weather_data.get(city, {"晴": 20})
condition = random.choice(list(city_weather.keys()))
temperature = city_weather[condition]
return f"{city} {date} 天气{condition},气温{temperature}°C"
5.2 完整调用代码
# weather_bot_complete.py
import requests
import json
HolySheep API 配置
API_KEY = "YOUR_HOLYSHEEP_API_KEY" # 替换成你的真实 API Key
BASE_URL = "https://api.holysheep.ai/v1"
def query_weather(user_message: str):
"""
使用 Function Calling 查询天气
"""
# 工具定义
tools = [
{
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,例如:北京、上海、东京"
},
"date": {
"type": "string",
"description": "查询日期,格式为 YYYY-MM-DD"
}
},
"required": ["city", "date"]
}
}
]
# 构造请求
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "claude-3-5-sonnet-20241022",
"messages": [
{"role": "user", "content": user_message}
],
"tools": tools,
"tool_choice": "auto" # 让 Claude 自动决定是否调用工具
}
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload
)
result = response.json()
print("Claude 响应:", json.dumps(result, ensure_ascii=False, indent=2))
return result
测试运行
if __name__ == "__main__":
# 第一次调用:Claude 会决定是否使用工具
result1 = query_weather("北京明天天气怎么样?")
# 查看是否有工具调用
if "choices" in result1 and len(result1["choices"]) > 0:
message = result1["choices"][0]["message"]
if "tool_calls" in message:
print("\n🔥 检测到工具调用!Claude 决定使用 get_weather")
for tool_call in message["tool_calls"]:
print(f"工具名:{tool_call['function']['name']}")
print(f"参数:{tool_call['function']['arguments']}")
5.3 运行结果解析
(图示:命令行输出 Claude 返回的 tool_calls 信息)
运行上面的代码,你会看到类似这样的输出:
Claude 响应:{
"choices": [
{
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_12345",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\": \"北京\", \"date\": \"2026-01-16\"}"
}
}
]
}
}
]
}
🔥 检测到工具调用!Claude 决定使用 get_weather
工具名:get_weather
参数:{"city": "北京", "date": "2026-01-16"}
看到了吗?Claude 自动识别了你的问题,提取出“北京”和“明天日期”,并决定调用 get_weather 工具!
六、JSON Schema 实战:结构化数据输出
上一节我们让 Claude 调用工具,但有时候你可能不需要调用真实工具,而是希望 Claude 直接按照指定格式返回数据。这时就要用到 JSON Schema 强制约束输出格式。
6.1 基础结构化输出
# structured_output.py
import requests
import json
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
BASE_URL = "https://api.holysheep.ai/v1"
def extract_structured_data(user_text: str):
"""
使用 JSON Schema 强制输出结构化数据
场景:从用户输入中提取个人信息
"""
# 定义输出格式规范(JSON Schema)
response_format = {
"type": "json_object",
"properties": {
"姓名": {
"type": "string",
"description": "从文本中提取的人名"
},
"年龄": {
"type": "integer",
"description": "从文本中提取的年龄"
},
"职业": {
"type": "string",
"description": "从文本中提取的职业"
},
"城市": {
"type": "string",
"description": "从文本中提取的城市"
}
},
"required": ["姓名", "年龄", "职业", "城市"]
}
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "claude-3-5-sonnet-20241022",
"messages": [
{"role": "user", "content": user_text}
],
"response_format": response_format
}
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload
)
result = response.json()
# 提取 Claude 返回的内容
if "choices" in result:
content = result["choices"][0]["message"]["content"]
return json.loads(content)
return None
测试运行
if __name__ == "__main__":
test_text = "我叫张三,今年28岁,是一名软件工程师,目前在北京工作"
result = extract_structured_data(test_text)
print("提取结果:")
print(json.dumps(result, ensure_ascii=False, indent=2))
# 验证数据结构
print("\n✅ 数据验证:")
print(f"姓名:{result['姓名']}")
print(f"年龄:{result['年龄']} 岁")
print(f"职业:{result['职业']}")
print(f"城市:{result['城市']}")
6.2 高级嵌套结构
有时候你需要返回更复杂的数据结构,比如订单信息包含多个商品:
# order_extraction.py
import requests
import json
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
BASE_URL = "https://api.holysheep.ai/v1"
def extract_order_info(user_text: str):
"""
提取嵌套结构的订单信息
"""
response_format = {
"type": "json_object",
"properties": {
"订单号": {
"type": "string",
"description": "订单编号"
},
"下单时间": {
"type": "string",
"description": "下单时间,格式 YYYY-MM-DD HH:MM"
},
"收货人": {
"type": "string",
"description": "收货人姓名"
},
"联系电话": {
"type": "string",
"description": "手机号或固定电话"
},
"配送地址": {
"type": "string",
"description": "详细收货地址"
},
"商品列表": {
"type": "array",
"description": "购买的商品详情",
"items": {
"type": "object",
"properties": {
"商品名称": {"type": "string"},
"数量": {"type": "integer"},
"单价": {"type": "number"},
"小计": {"type": "number"}
}
}
},
"总金额": {
"type": "number",
"description": "订单总金额,单位元"
},
"支付方式": {
"type": "string",
"enum": ["微信支付", "支付宝", "银行卡", "货到付款"],
"description": "支付方式"
}
},
"required": ["订单号", "收货人", "商品列表", "总金额"]
}
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "claude-3-5-sonnet-20241022",
"messages": [
{"role": "system", "content": "你是一个订单信息提取助手,请严格按照给定格式返回信息。"},
{"role": "user", "content": user_text}
],
"response_format": response_format
}
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload
)
return response.json()
测试
if __name__ == "__main__":
test_order = """
订单编号:A20260115B00123
下单时间:2026年1月15日下午3点30分
收货人:李四
联系电话:13812345678
配送地址:上海市浦东新区世纪大道100号
购买商品:
- iPhone 16 Pro 手机 1台,单价8999元
- 无线蓝牙耳机 2副,单价299元
- 手机保护壳 3个,单价59元
总计:9653元
支付方式:微信支付
"""
result = extract_order_info(test_order)
if "choices" in result:
order_data = json.loads(result["choices"][0]["message"]["content"])
print("📦 订单信息:")
print(json.dumps(order_data, ensure_ascii=False, indent=2))
print(f"\n💰 订单总额:¥{order_data['总金额']}")
print(f"📍 收货人:{order_data['收货人']}")
print(f"📱 商品数量:{len(order_data['商品列表'])} 种")
七、完整实战:智能客服机器人
现在让我们综合运用 Function Calling 和 JSON Schema,写一个完整的智能客服机器人:
# customer_service_bot.py
import requests
import json
from datetime import datetime
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
BASE_URL = "https://api.holysheep.ai/v1"
定义可调用的工具
tools = [
{
"name": "查询订单状态",
"description": "查询用户订单的物流状态",
"parameters": {
"type": "object",
"properties": {
"订单号": {
"type": "string",
"description": "10位订单编号,例如:A20260115B00123"
}
},
"required": ["订单号"]
}
},
{
"name": "查询商品库存",
"description": "查询某商品当前库存数量",
"parameters": {
"type": "object",
"properties": {
"商品名称": {
"type": "string",
"description": "商品完整名称"
},
"颜色": {
"type": "string",
"description": "商品颜色(可选)"
},
"尺码": {
"type": "string",
"description": "商品尺码,如 S/M/L/XL(可选)"
}
},
"required": ["商品名称"]
}
},
{
"name": "计算退款金额",
"description": "根据订单和退款原因计算可退款金额",
"parameters": {
"type": "object",
"properties": {
"订单号": {
"type": "string",
"description": "订单编号"
},
"退款原因": {
"type": "string",
"description": "退款原因:质量问题/七天无理由/发错货/其他"
}
},
"required": ["订单号", "退款原因"]
}
}
]
模拟数据库查询
def mock_database_query(tool_name: str, arguments: dict):
"""模拟数据库查询"""
if tool_name == "查询订单状态":
order_id = arguments.get("订单号", "")
return {
"状态": "配送中",
"快递公司": "顺丰速运",
"运单号": "SF1234567890",
"预计送达": "2026-01-18",
"当前位置": "上海市浦东分拨中心"
}
elif tool_name == "查询商品库存":
product = arguments.get("商品名称", "")
return {
"商品名称": product,
"库存数量": 128,
"仓库": "华东仓"
}
elif tool_name == "计算退款金额":
return {
"订单号": arguments.get("订单号"),
"订单总额": 9653.00,
"退款金额": 9653.00,
"退款方式": "原路退回",
"到账时间": "3-5个工作日"
}
return {}
def chat_with_customer_service(user_message: str):
"""
智能客服对话主函数
"""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "claude-3-5-sonnet-20241022",
"messages": [
{
"role": "system",
"content": """你是一个专业、耐心的电商客服。请根据用户问题判断是否需要调用工具。
可用工具:查询订单状态、查询商品库存、计算退款金额。
如果用户问题涉及以上三个方面,请使用对应工具获取信息后回答。"""
},
{"role": "user", "content": user_message}
],
"tools": tools,
"tool_choice": "auto"
}
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload
)
result = response.json()
# 检查是否有工具调用
if "choices" in result and len(result["choices"]) > 0:
message = result["choices"][0]["message"]
if "tool_calls" in message:
print("🤖 Claude 决定调用工具,正在执行...\n")
# 处理每个工具调用
tool_results = []
for tool_call in message["tool_calls"]:
tool_name = tool_call["function"]["name"]
args = json.loads(tool_call["function"]["arguments"])
print(f"📞 调用工具:{tool_name}")
print(f"📝 参数:{json.dumps(args, ensure_ascii=False)}")
# 执行模拟查询
tool_result = mock_database_query(tool_name, args)
print(f"📦 查询结果:{json.dumps(tool_result, ensure_ascii=False)}\n")
tool_results.append({
"tool_call_id": tool_call["id"],