内置网页搜索
设置 web_search: true,模型就会用实时搜索结果为答案提供依据。
POST https://api.shannon-ai.com/v1/chat/completions
from openai import OpenAI
client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1")
response = client.chat.completions.create(
model="shannon-3",
messages=[{"role": "user", "content": "What is the weather forecast for Lisbon this weekend?"}],
extra_body={"web_search": True}, # a Shannon field, so it goes in extra_body
)
print(response.choices[0].message.content) import OpenAI from "openai";
const client = new OpenAI({ apiKey: "YOUR_API_KEY", baseURL: "https://api.shannon-ai.com/v1" });
const response = await client.chat.completions.create({
model: "shannon-3",
messages: [{ role: "user", content: "What is the weather forecast for Lisbon this weekend?" }],
web_search: true,
});
console.log(response.choices[0].message.content); curl https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"messages": [
{"role": "user", "content": "What is the weather forecast for Lisbon this weekend?"}
],
"web_search": true
}' 回复是普通的 chat completion,另有两处补充。答案用方括号中的数字指向搜索结果,sources 说明每个数字对应哪条结果,annotations 标出每条结果在哪里被引用:
200 JSON
{
"id": "chatcmpl-3e5a7c9b1d2f4a6c8e0b2d4f6a8c1e3b",
"object": "chat.completion",
"created": 1791590400,
"model": "shannon-3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Saturday in Lisbon is forecast to be sunny with a high near 24 °C [1]. Sunday turns cloudy, with a chance of light rain in the afternoon [2].",
"reasoning_content": null,
"annotations": [
{
"type": "url_citation",
"url_citation": {
"start_index": 66,
"end_index": 69,
"url": "https://weather.example/lisbon/weekend",
"title": "Lisbon weather: weekend outlook"
}
},
{
"type": "url_citation",
"url_citation": {
"start_index": 137,
"end_index": 140,
"url": "https://forecast.example/pt/lisbon/sunday",
"title": "Sunday forecast for Lisbon"
}
}
]
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 2874,
"completion_tokens": 41,
"total_tokens": 2915
},
"sources": [
{
"index": 1,
"title": "Lisbon weather: weekend outlook",
"url": "https://weather.example/lisbon/weekend"
},
{
"index": 2,
"title": "Sunday forecast for Lisbon",
"url": "https://forecast.example/pt/lisbon/sunday"
},
{
"index": 3,
"title": "Portugal: the week ahead",
"url": "https://news.example/portugal/weather-week"
}
]
} 开启搜索
搜索是请求的一个字段,默认关闭。除非请求发送该字段,否则不会进行任何搜索。
| 字段 | 类型 | 默认值 | 说明 | 适用模型 |
|---|---|---|---|---|
web_search | boolean | false | true 会为该请求运行一次联网搜索,并在模型作答之前把结果交给它。 | 除 shannon-coder-1 之外的所有 Shannon 模型 |
| 端点 | 联网搜索 | 方式 |
|---|---|---|
/v1/chat/completions | 是 | 请求体中的 "web_search": true。 |
/v1/messages | 是 | 请求体中的 "web_search": true。 |
/v1/responses | — | 此端点仅凭模型本身作答。若要得到带搜索的答案,请使用上面两个端点之一。 |
在 /v1/messages 上,该字段位于请求体顶层,与 model 和 messages 并列:
请求体
{
"model": "shannon-3",
"web_search": true,
"messages": [
{
"role": "user",
"content": "What is the weather forecast for Lisbon this weekend?"
}
]
} 带搜索的请求会做什么
- API 针对最后一条用户消息搜索网络。对话中较早的轮次为搜索提供上下文。
- 每个发送
web_search: true的请求都会运行搜索。是否搜索不由模型决定。 - 结果会作为带编号的来源放在模型面前,模型据此写出答案。
- 回复在搜索完成时开始。流式请求在此之前不会发送任何内容,既没有标头也没有事件,所以请为第一个数据块预留更长的等待时间。
回复包含什么
- 回复采用其端点通常的结构。答案位于
choices[0].message.content(在/v1/messages上是text块)。 - 文本中可能带有
[1]、[2]之类的标记,位于它们所支持的陈述之后。每个数字对应模型读取的其中一条结果。 sources列出这些结果:交给模型的每条结果对应一个条目,包含index、title和url。标记[1]就是index为 1 的条目。答案没有引用的结果也会列出。- 在
/v1/chat/completions上,消息还带有 OpenAI 格式的annotations:标记所指的每个来源对应一个url_citation,包含url、title,以及start_index和end_index,即标记在content中的位置,按字符计数(不含结束位置)。 - 在流式输出中,
sources随最后一个 chunk 一起到达,在/v1/messages上则随message_delta事件到达。annotations 在最后一个 chunk 之前的那个 chunk 中到达,形式为delta.annotations。 - 只有本次请求的搜索找到了结果时才会有
sources。没有它的回复是在没有搜索结果的情况下写成的。
搜索如何计数
每个计划每天都包含一定次数的搜索:
| 计划 | 每日搜索次数 |
|---|---|
| 免费 | 3 |
| 加号 | 30 |
| Standard | 50 |
| 专业 | 60 |
- 搜索到内容的请求会用掉当日额度中的一次搜索。没有搜到内容的搜索不占用额度。
- 聊天和 API 共用密钥所属账户的额度。
- 计数每天 00:00 UTC 重新开始。
- 搜索结果是请求的输入 tokens,与 prompt 的其余部分一起计费。
当天的搜索次数用完时
在当天最后一次搜索之后发送 web_search: true 的请求不会被拒绝。它会在不搜索的情况下作答:状态码为 200,回复中没有 sources。
把搜索作为你自己的工具
web_search: true 是这里所述搜索的唯一开关。你在 tools 中定义并命名为 web_search 的函数是你自己的工具:模型返回一个调用,由你的代码运行搜索并把结果发回。
其他平台的搜索工具类型,例如 /v1/messages 上的 web_search_20250305 或 /v1/responses 上的 {"type": "web_search"},在这里不会启动搜索。
错误
联网搜索不增加任何状态码或错误类型。没有搜到内容的搜索,或当天已没有剩余搜索次数,会给出不含搜索结果的正常答案。其他所有错误与不带搜索的请求相同。 错误处理