내장 웹 검색
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는 각 출처가 인용된 위치를 표시합니다.
{
"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에서는 메시지에annotations도 있으며 OpenAI 형식을 따릅니다. 표시가 가리키는 출처마다url_citation이 하나씩 있고url,title,start_index,end_index를 포함합니다. 두 인덱스는content에서 표시가 있는 위치를 문자 수로 센 값입니다(끝 값은 포함되지 않습니다).- 스트림에서
sources는 마지막 청크와 함께 오고,/v1/messages에서는message_delta이벤트와 함께 옵니다. annotations는 마지막 청크 바로 앞의 청크 하나에delta.annotations로 들어 있습니다. sources는 이 요청의 검색에서 결과를 찾았을 때만 있습니다. 이것이 없는 응답은 검색 결과 없이 작성된 것입니다.
검색 횟수가 계산되는 방식
모든 플랜에는 하루 검색 횟수가 포함되어 있습니다.
| 플랜 | 하루 검색 횟수 |
|---|---|
| 무료 | 3 |
| 플러스 | 30 |
| Standard | 50 |
| 프로 | 60 |
- 검색에서 결과를 찾은 요청은 그날 할당량에서 검색 한 번을 사용합니다. 아무것도 찾지 못한 검색은 사용하지 않습니다.
- 채팅과 API는 키를 소유한 계정의 할당량을 함께 사용합니다.
- 횟수는 매일 00:00 UTC에 다시 시작됩니다.
- 검색 결과는 요청의 입력 토큰이며 프롬프트의 나머지와 함께 청구됩니다.
하루 검색 횟수를 모두 사용했을 때
하루의 마지막 검색 이후에 web_search: true를 보낸 요청은 거부되지 않습니다. 검색 없이 응답합니다. 상태는 200이고 응답에는 sources가 없습니다.
자체 도구로서의 검색
web_search: true는 여기서 설명하는 검색의 유일한 스위치입니다. tools에 정의하고 이름을 web_search로 붙인 함수는 사용자 자신의 도구입니다. 모델이 호출을 반환하면 코드가 검색을 실행하고 결과를 되돌려 보냅니다.
/v1/messages의 web_search_20250305나 /v1/responses의 {"type": "web_search"}처럼 다른 플랫폼의 검색 도구 type은 여기서 검색을 시작하지 않습니다.
오류
웹 검색은 상태 코드나 오류 type을 추가하지 않습니다. 아무것도 찾지 못한 검색이나 남은 검색이 없는 날에는 검색 결과 없이 일반적인 답변이 옵니다. 그 밖의 오류는 검색 없는 요청과 같습니다. 오류 처리