Appearance
Kimi API 提供 $web_search 内置工具,不需要自己实现搜索抓取逻辑,模型会处理搜索结果并生成回答。使用时需将 type 设置为 builtin_function,且必须禁用 thinking 模式。本文提供完整使用示例。
使用 Kimi API 的联网搜索($web_search)
与自定义搜索工具的区别
| 特性 | $web_search 内置工具 | 自定义 search 工具 |
|---|---|---|
| 实现复杂度 | 只需注册,无需实现 | 需要自己调用搜索 API |
| 搜索质量 | Kimi 官方搜索能力 | 取决于你选择的搜索服务 |
| 费用 | 按搜索次数额外计费 | 取决于搜索服务费用 |
| thinking 兼容性 | 必须禁用 thinking | 兼容 thinking 模式 |
基础用法
python
import json
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ.get("MOONSHOT_API_KEY"),
base_url="https://api.moonshot.cn/v1",
)
tools = [
{
"type": "builtin_function", # 注意:是 builtin_function,不是 function
"function": {"name": "$web_search"} # 固定名称,无需参数说明
}
]
messages = [
{"role": "system", "content": "你是一个能联网查询最新信息的助手。"},
{"role": "user", "content": "今天 OpenAI 有什么新闻?"}
]
# 使用 $web_search 时必须禁用 thinking
while True:
response = client.chat.completions.create(
model="kimi-k2.6",
messages=messages,
tools=tools,
extra_body={"thinking": {"type": "disabled"}}, # 必须禁用
)
choice = response.choices[0]
if choice.finish_reason != "tool_calls":
print(choice.message.content)
break
messages.append(choice.message)
for tool_call in choice.message.tool_calls:
# 关键:原样返回 arguments,不做任何处理
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": tool_call.function.arguments, # 原样返回!
})混合使用内置和自定义工具
可以同时注册 builtin_function 和普通 function:
python
tools = [
{
"type": "builtin_function",
"function": {"name": "$web_search"}
},
{
"type": "function",
"function": {
"name": "get_local_data",
"description": "查询本地数据库中的信息",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string"}
},
"required": ["query"]
}
}
}
]执行时,按 tool_call.function.name 判断调用哪个工具:
python
if tool_call.function.name == "$web_search":
# 原样返回 arguments
result = tool_call.function.arguments
elif tool_call.function.name == "get_local_data":
# 执行自定义逻辑
args = json.loads(tool_call.function.arguments)
result = query_local_db(args["query"])Token 消耗统计
$web_search 会产生额外的 token 消耗(搜索结果内容):
python
# 响应中包含搜索相关的 token 统计
print(response.usage)
# search_content_total_tokens: 搜索结果消耗的 token
# chat_total_tokens: 对话本身消耗的 token具体定价见联网搜索价格说明。
常见问题
Q: 为什么使用 $web_search 必须禁用 thinking?
A: 官方限制,内置联网搜索工具与 thinking 模式不兼容。如需 thinking + 联网,可以自行实现搜索工具(调用 Tavily 等 API),此时不受此限制。
Q: $web_search 的搜索结果质量如何?
A: 使用 Kimi 官方联网能力,中文搜索效果较好。如需精确控制搜索源或需要更高质量的搜索,建议自行实现工具调用搜索 API。
Q: 执行 $web_search 工具时为什么要"原样返回 arguments"?
A: 这是 $web_search 的特殊设计,Kimi 服务端识别到 arguments 原样返回后,会自动执行搜索并将结果注入上下文,开发者不需要(也无法)自己做搜索。
Kimi API 的 $web_search 是内置联网搜索工具,通过 type: "builtin_function" 注册,执行时将 arguments 原样返回给 API 即可,由 Kimi 负责实际搜索和网页阅读。注意:使用时必须禁用 thinking 模式,并推荐使用 kimi-k2.6 模型。
使用 Kimi API 的联网搜索功能
两种联网搜索方式的对比
| 方式 | 工作量 | 适合场景 |
|---|---|---|
| 自定义 tool_calls | 需要自己实现搜索 + 网页抓取 | 需要精确控制搜索源、使用特定搜索引擎 |
| $web_search 内置工具 | 开箱即用,几乎零配置 | 快速接入,不需要自己维护搜索基础设施 |
注册 $web_search
$web_search 使用特殊的 type: "builtin_function" 声明,不需要提供参数说明:
typescript
const tools = [
{
type: "builtin_function", // 区别于普通 "function"
function: {
name: "$web_search", // 以 $ 开头代表内置工具
},
},
];注意:使用
$web_search时必须通过thinking: { type: "disabled" }禁用思考模式。
完整调用示例
typescript
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.MOONSHOT_API_KEY,
baseURL: "https://api.moonshot.cn/v1",
});
async function chat(messages: any[]) {
return await (client as any).chat.completions.create({
model: "kimi-k2.6", // 推荐用 kimi-k2.6,上下文更大,更适合处理搜索结果
messages,
max_tokens: 32768,
thinking: { type: "disabled" }, // $web_search 必须禁用 thinking
tools: [
{
type: "builtin_function",
function: { name: "$web_search" },
},
],
});
}
const messages: any[] = [
{ role: "system", content: "你是 Kimi,由 Moonshot AI 提供的人工智能助手。" },
{ role: "user", content: "请搜索 Context Caching 技术,告诉我它是什么。" },
];
let finishReason = null;
while (finishReason === null || finishReason === "tool_calls") {
const completion = await chat(messages);
const choice = completion.choices[0];
finishReason = choice.finish_reason;
if (finishReason === "tool_calls") {
messages.push(choice.message);
for (const toolCall of choice.message.tool_calls) {
const args = JSON.parse(toolCall.function.arguments);
// 关键:$web_search 只需要原样返回 arguments,不需要实际执行搜索
messages.push({
role: "tool",
tool_call_id: toolCall.id,
name: toolCall.function.name,
content: JSON.stringify(args), // 原样返回,Kimi 自己执行搜索
});
}
}
}
console.log(messages.at(-1).content);python
import os
import json
from openai import OpenAI
client = OpenAI(
base_url="https://api.moonshot.cn/v1",
api_key=os.environ.get("MOONSHOT_API_KEY"),
)
def search_impl(arguments):
# $web_search 只需要原样返回参数,Kimi 负责实际搜索
return arguments
messages = [
{"role": "system", "content": "你是 Kimi,由 Moonshot AI 提供的人工智能助手。"},
{"role": "user", "content": "请搜索 Context Caching 技术,告诉我它是什么。"},
]
finish_reason = None
while finish_reason is None or finish_reason == "tool_calls":
completion = client.chat.completions.create(
model="kimi-k2.6",
messages=messages,
max_tokens=32768,
extra_body={"thinking": {"type": "disabled"}},
tools=[{"type": "builtin_function", "function": {"name": "$web_search"}}],
)
choice = completion.choices[0]
finish_reason = choice.finish_reason
if finish_reason == "tool_calls":
messages.append(choice.message)
for tool_call in choice.message.tool_calls:
args = json.loads(tool_call.function.arguments)
tool_result = search_impl(args)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"name": tool_call.function.name,
"content": json.dumps(tool_result),
})
print(choice.message.content)内置工具运作原理
$web_search 是服务端执行的内置工具:
- 模型返回
finish_reason: "tool_calls",表示需要搜索 - 你把
arguments原样回传给 API(不需要实际搜索) - Kimi 服务端接收到后,自动执行搜索 + 网页阅读
- 搜索结果注入到下一次请求的上下文中
- 模型基于搜索结果生成最终回复
Token 消耗监控
搜索结果会大幅增加 token 消耗,可以从 arguments 中提前获知:
python
for tool_call in choice.message.tool_calls:
args = json.loads(tool_call.function.arguments)
# usage.total_tokens 表示本次搜索结果预计占用的 token 数
search_tokens = args.get("usage", {}).get("total_tokens", 0)
print(f"本次搜索预计消耗 {search_tokens} tokens")典型消耗示例:
search_content_total_tokens: 13046 ← 搜索结果占用的 token
chat_prompt_tokens: 13212 ← 包含搜索结果的总输入 token
chat_completion_tokens: 295 ← 模型回复消耗
chat_total_tokens: 13507 ← 总消耗注意事项
- 使用
$web_search时必须用kimi-k2.6,以应对搜索结果带来的大量 token 输入 - 联网搜索除 token 费用外,还会额外计算调用次数费用,详见联网搜索计费
$web_search可以和普通function混合放在同一个tools数组中- 从自定义搜索迁移到
$web_search:只需改tools定义 +search_impl函数,其他代码不变
常见问题
Q: 为什么 $web_search 执行时要原样返回 arguments?
A: 因为实际搜索是由 Kimi 服务端执行的,arguments 实际上是搜索的"任务令牌"——把它原样传回去,Kimi 才知道要执行哪次搜索。你不需要、也不能替换成自己的搜索结果。
Q: 可以和自定义工具一起用吗?
A: 可以。type: "builtin_function" 和 type: "function" 可以在同一个 tools 数组中共存。
Q: 搜索结果不准怎么办?
A: 可以在 user 消息里更明确地描述搜索需求,或者切换到自定义 tool_calls 方式,自己接入特定的搜索引擎(如 Bing API、Tavily 等)。