大模型的训练数据存在截止时间,且无法获取用户的实时私有数据。为了让 AI 回答"今天北京的天气"或"公司最新的季度营收",必须让模型具备调用外部工具的能力。
核心机制:Function Calling(工具调用)
现代大模型(GPT-4、Claude、Kimi 等)支持在对话中识别何时需要外部数据,并生成标准化的工具调用请求。流程如下:
- 用户提问 → 2. 模型判断需搜索 → 3. 系统执行搜索 → 4. 结果回传给模型 → 5. 模型生成最终回答
基础实现示例
以下使用 OpenAI 接口演示如何让模型自主调用搜索工具:
import openai
import requests
# 1. 定义工具(JSON Schema 格式)
tools = [{
"type": "function",
"function": {
"name": "web_search",
"description": "搜索实时网络信息",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "搜索关键词"}
},
"required": ["query"]
}
}
}]
# 2. 模拟搜索函数(实际可替换为 Serper/Google API)
def web_search(query):
# 这里调用真实的搜索 API,如 Serper.dev 或 Bing API
return f"搜索结果:关于'{query}'的最新信息是..."
# 3. 对话流程
messages = [{"role": "user", "content": "Python 3.12 有什么新特性?"}]
# 第一次调用:模型决定使用工具
response = openai.chat.completions.create(
model="gpt-4",
messages=messages,
tools=tools,
tool_choice="auto"
)
# 4. 如果模型要求调用工具
if response.choices[0].finish_reason == "tool_calls":
tool_call = response.choices[0].message.tool_calls[0]
query = eval(tool_call.function.arguments)["query"]
# 执行搜索
search_result = web_search(query)
# 将结果追加到对话历史
messages.append(response.choices[0].message)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": search_result
})
# 第二次调用:模型基于搜索结果回答
final_response = openai.chat.completions.create(
model="gpt-4",
messages=messages
)
print(final_response.choices[0].message.content)
实际应用中的关键点
| 考量项 | 建议做法 |
|--------|----------|
| 搜索 API 选择 | 开发测试可用 DuckDuckGo(免费),生产环境推荐 Serper.dev 或 Bing Search API(稳定且支持中文) |
| 延迟控制 | 网络搜索增加 1-3 秒延迟,需在前端添加"正在搜索..."状态提示 |
| 上下文长度 | 搜索结果通常截取前 3-5 条网页摘要(约 1000 tokens),避免超出模型上下文限制 |
| 成本控制 | 搜索 API 按次计费(约 $0.001-0.005/次),建议对常见问题启用本地缓存 |
常见陷阱
- 循环调用:模型可能对模糊问题反复搜索,需设置最大调用次数(如最多 3 次)。
- 信息过时:搜索引擎返回的网页可能包含旧信息,建议在 prompt 中要求模型关注发布日期。
- 隐私风险:用户敏感信息(如病历、密码)不应发送至公共搜索引擎,需先做脱敏或改用私有知识库。
通过 Function Calling 接入外部信息,是解决大模型"幻觉"和"知识过期"最直接有效的方式,也是构建 Agent 的基础能力。