快速回答
如何给 OpenAI 模型一个网页搜索工具?
在 tools 中用 JSON Schema 声明一个 google_search 函数,然后循环:当模型返回 tool_calls 时,在 https://serpcrypto.com/api/v1/search 上运行每次查询,并把结果作为 tool 消息追加,直到它给出答案。SerpCrypto 每次成功查询收取 1 个积分,起价为 US$0.30/千次搜索,用加密货币支付,无需 KYC。
工具 schema 是什么样的?
一个 function 工具包含名称、描述和 JSON Schema 格式的参数。模型只能看到这三样东西,因此描述必须说明该工具返回什么以及何时使用它。只有 query 是必填的;country 和 language 是可选的,在代码中默认为 US English。
{
"type": "function",
"function": {
"name": "google_search",
"description": "Search Google for current information. Returns the top results with title, link and snippet. Use it for facts newer than your training data.",
"parameters": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "The search query, as a person would type it." },
"gl": { "type": "string", "description": "Two-letter country code of the results, e.g. us, gb, de." },
"hl": { "type": "string", "description": "Language code, e.g. en, de, pt-BR." }
},
"required": ["query"]
}
}
}工具调用循环是怎么运作的?
用 tools 发送问题。如果回复中包含 tool_calls,就逐个执行,追加 assistant 消息,并为每次调用追加一条带有对应 tool_call_id 的 tool 消息,然后再次调用模型。当某条回复没有任何工具调用时,它就是最终答案。
下面的循环在三次查询后停止。如果模型不断查询,上限可以保护你的积分,而三次查询就能回答大多数事实性问题。
"""Tool-calling loop: the model asks for searches, this code runs them on SerpCrypto."""
import json
import os
import requests
from openai import OpenAI
client = OpenAI() # reads OPENAI_API_KEY
MODEL = os.environ["OPENAI_MODEL"] # any OpenAI chat model with tool calling
API_URL = "https://serpcrypto.com/api/v1/search"
TOOLS = [
{
"type": "function",
"function": {
"name": "google_search",
"description": "Search Google for current information. Returns the top results with title, link and snippet.",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "The search query."},
"gl": {"type": "string", "description": "Two-letter country code, e.g. us."},
"hl": {"type": "string", "description": "Language code, e.g. en."},
},
"required": ["query"],
},
},
}
]
def google_search(query, gl="us", hl="en"):
r = requests.get(
API_URL,
params={"q": query, "gl": gl, "hl": hl},
headers={"Authorization": "Bearer " + os.environ["SERPCRYPTO_API_KEY"]},
timeout=90,
)
if r.status_code != 200:
return f"Search failed with HTTP {r.status_code}."
items = r.json().get("organic_results", [])[:5]
return "\n\n".join(f"{x['title']}\n{x['link']}\n{x.get('snippet', '')}" for x in items) or "No results."
def ask(question, max_searches=3):
messages = [{"role": "user", "content": question}]
for _ in range(max_searches + 1):
reply = client.chat.completions.create(model=MODEL, messages=messages, tools=TOOLS)
msg = reply.choices[0].message
if not msg.tool_calls:
return msg.content
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
messages.append({"role": "tool", "tool_call_id": call.id, "content": google_search(**args)})
return "Stopped: search limit reached."
print(ask("Which countries changed their data protection laws in 2026? Cite sources."))同一份 schema 也适用于 Claude 和其他模型吗?
适用,只是封装不同。Claude 的 tool use 在 input_schema 下接受相同的 JSON Schema,与 name 和 description 并列。大多数其他支持工具调用的 API 在参数上也接受 JSON Schema,只是外层字段名不同。搜索函数本身保持不变,因为它只调用 SerpCrypto endpoint。
{
"name": "google_search",
"description": "Search Google for current information. Returns the top results with title, link and snippet.",
"input_schema": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "The search query." },
"gl": { "type": "string", "description": "Two-letter country code, e.g. us." },
"hl": { "type": "string", "description": "Language code, e.g. en." }
},
"required": ["query"]
}
}工具应该向模型返回什么?
带链接的简短文本。五条包含标题、链接和摘要的结果通常就足够模型回答和引用。返回完整 JSON 也行,但会消耗更多 token,并给模型更多噪声去读。
如果存在 AI Overview 文本,可以加上,让模型看到 Google 自己的摘要,并保留来源链接,这样答案可以引用页面而不是概述。
如何让搜索成本可预测?
统计工具调用:每次成功调用计 1 积分。像循环那样为每个问题限制查询次数,并用查询词记录每次调用,这样你能看到模型在问什么。在 100,000 次搜索 套餐上费率为 US$0.56/千次搜索,并且 预付的搜索积分永不过期:未使用的查询会一直留在你的账户中,直到你使用它们。
出错不扣费:1 积分 = 1 次成功的查询请求,可在任意支持的引擎上返回一页结果。失败的请求不计费。
Function calling 常见问题
可以用 Responses API 代替 Chat Completions 吗?
可以。Responses API 接受带有相同 JSON Schema 的 function 工具,其中 name、description 和 parameters 位于每个工具的顶层。搜索函数和循环的思路都不变。
为什么不使用模型提供商内置的网页搜索?
内置搜索工具会自行选择来源和设置。在 SerpCrypto 上使用 function,可以按你选择的国家和语言获取 Google 搜索结果,以可记录的 JSON 返回,每次查询价格已知。
模型能选择国家吗?
能。gl 是工具的一个 parameter,所以模型可以根据问题来设置它,例如针对关于英国的问题设为 gb。对于没有提到国家的问题,在代码中保留默认值。
获取搜索 API 密钥需要信用卡吗?
不需要。SerpCrypto 积分用 BTC, USDT, USDC, ETH, SOL, LTC 支付,无需身份证、无需自拍、无需证件。使用账号登录;邮箱为选填。