Trả lời nhanh
Làm cách nào để thêm tìm kiếm web vào một model OpenAI với function calling?
Khai báo một hàm search_web với JSON schema, và khi model gọi nó, hãy POST truy vấn tới https://llmwebsearch.com/api/v1/search của LLMWebSearch. Trả lại các nguồn đã đánh số, với 3 trang hàng đầu dưới dạng Markdown, dưới dạng function_call_output; model trả lời và trích dẫn chúng. Mỗi lần tìm kiếm tốn 1 credit, từ 1,20 US$/1K lượt tìm kiếm tính đến tháng 10 năm 2026. Không cần KYC; thanh toán bằng crypto.
Những gì bạn cần
| Package | openai và requests (hoặc openai-agents cho phiên bản Agents SDK) |
|---|---|
| Khóa | OPENAI_API_KEY cho model, LLMWEBSEARCH_API_KEY cho tìm kiếm |
| Model | Bất kỳ model nào hỗ trợ function calling, được đặt trong OPENAI_MODEL |
| API được dùng | Responses API: client.responses.create với tools và input |
| Tính phí phía chúng tôi | Một credit trả cho một lượt tìm kiếm: tối đa 20 kết quả được xếp hạng, với nội dung của 3 trang đầu được đọc và trả về dưới dạng Markdown. Đọc từ 4 đến 10 trang thì tính 2 credit. Lượt gọi kết thúc bằng lỗi không tốn gì |
Tool schema trông như thế nào?
Một function tool có một name, một description và JSON Schema parameters. Hãy giữ phần mô tả cụ thể: công cụ trả về cái gì, và rằng các nguồn nên được trích dẫn theo số. Hai parameter là đủ cho hầu hết các agent: query, và bao nhiêu kết quả hàng đầu cần read đầy đủ.
Model không bao giờ thấy khóa API của bạn. Nó chỉ đề xuất các đối số; mã của bạn quyết định cách gọi API và cách gửi trả lại.
Vòng lặp gọi hoạt động thế nào?
Gửi tin nhắn của người dùng kèm theo các tool. Nếu phản hồi chứa các item kiểu function_call, hãy phân tích JSON arguments của từng item, chạy tìm kiếm, và thêm vào một function_call_output với cùng call_id. Sau đó gọi model lần nữa với danh sách đầu vào dài hơn. Khi một phản hồi không chứa lời gọi hàm nào, văn bản của nó chính là câu trả lời.
Vòng lặp bên dưới dừng sau năm vòng, một chốt chặn với model cứ tiếp tục tìm kiếm. Hướng dẫn function calling của OpenAI mô tả cùng các item function_call và function_call_output, đọc ngày 22 tháng 10 năm 2026.
import json
import os
import requests
from openai import OpenAI
client = OpenAI()
MODEL = os.environ["OPENAI_MODEL"] # any model that supports function calling
SEARCH = "https://llmwebsearch.com/api/v1/search"
tools = [
{
"type": "function",
"name": "search_web",
"description": "Search the live web. Returns numbered sources with URLs; the first `read` include page text. Cite sources as [1], [2].",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "What to search for, as a person would type it."},
"read": {"type": "integer", "minimum": 0, "maximum": 10, "description": "How many top results to read in full."},
},
"required": ["query"],
"additionalProperties": False,
},
}
]
def search_web(query, read=3):
resp = requests.post(
SEARCH,
headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
json={"q": query, "max_results": 5, "read": read, "max_chars": 5000},
timeout=60,
)
if resp.status_code != 200:
return "Search failed: " + resp.json().get("error", {}).get("code", str(resp.status_code))
parts = []
for i, r in enumerate(resp.json()["results"], start=1):
text = r["content"] if r["content_status"] == "ok" else "(snippet only) " + r["snippet"]
parts.append(f"[{i}] {r['title']} - {r['url']}\n{text}")
return "\n\n".join(parts)
input_list = [{"role": "user", "content": "How should I size a Postgres connection pool?"}]
for _ in range(5):
response = client.responses.create(model=MODEL, tools=tools, input=input_list)
calls = [item for item in response.output if item.type == "function_call"]
if not calls:
print(response.output_text)
break
input_list += response.output
for item in calls:
args = json.loads(item.arguments)
output = search_web(args["query"], int(args.get("read", 3)))
input_list.append({"type": "function_call_output", "call_id": item.call_id, "output": output})
Có phiên bản ngắn hơn với Agents SDK không?
Có. OpenAI Agents SDK biến một hàm Python thành tool bằng một decorator và tự chạy vòng lặp gọi cho bạn. Tài liệu tools của nó, đọc ngày 22 tháng 10 năm 2026, trình bày decorator @tool từ agents.decorators, với phần mô tả lấy từ docstring và phần mô tả của từng đối số lấy từ mục Args của nó. Cùng trang đó cũng đề cập đến dạng @function_tool.
Runner.run_sync chạy agent cho đến khi nó tạo ra câu trả lời cuối cùng, gọi search_web bao nhiêu lần tùy theo model yêu cầu.
import os
import requests
from agents import Agent, Runner
from agents.decorators import tool
@tool
def search_web(query: str, read: int = 3) -> str:
"""Search the live web and return numbered sources with their URLs.
Args:
query: What to search for, as a person would type it.
read: How many top results to read in full, from 0 to 10.
"""
resp = requests.post(
"https://llmwebsearch.com/api/v1/search",
headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
json={"q": query, "max_results": 5, "read": max(0, min(read, 10)), "max_chars": 5000},
timeout=60,
)
resp.raise_for_status()
parts = []
for i, r in enumerate(resp.json()["results"], start=1):
text = r["content"] if r["content_status"] == "ok" else "(snippet only) " + r["snippet"]
parts.append(f"[{i}] {r['title']} - {r['url']}\n{text}")
return "\n\n".join(parts)
agent = Agent(
name="Researcher",
instructions="Answer from search_web results only and cite them as [1], [2].",
tools=[search_web],
)
result = Runner.run_sync(agent, "How should I size a Postgres connection pool?")
print(result.final_output)
Tại sao nên dùng công cụ API thay vì tìm kiếm web tích hợp của OpenAI?
Chủ yếu để kiểm soát những gì mô hình đọc và chi phí ra sao. Công cụ của chúng tôi đưa cho code của bạn các nguồn thô, kèm URL và văn bản trang, để bạn quyết định nội dung nào vào ngữ cảnh, có thể ghi log và lưu trữ. Chúng tôi không huấn luyện bất kỳ model nào trên truy vấn của bạn hay trên những gì API trả về, và chúng tôi không thêm quy tắc riêng nào chống lại việc lưu trữ kết quả; quyền của các trang có nội dung bạn đọc vẫn áp dụng.
Giá cũng được cố định theo mỗi lần tìm kiếm thay vì phụ thuộc vào lượng nội dung mô hình đọc được truy xuất. Bảng so sánh công cụ tích hợp đặt giá mỗi lần gọi của OpenAI, Anthropic, Google và các bên khác cạnh nhau, kèm ngày kiểm tra.
Làm sao để mô hình không tìm kiếm quá nhiều?
Hãy nói rõ trong hướng dẫn: tìm một lần, đọc các nguồn, chỉ tìm lại nếu chúng mâu thuẫn hoặc lạc đề. Giới hạn số vòng lặp trong vòng lặp của chính bạn, như đoạn script ở trên với con số năm.
Giữ max_chars ở mức vừa phải. Ba trang 5.000 ký tự tương đương khoảng 4.000 token mỗi lần tìm kiếm, và mỗi vòng lại cộng chúng vào đầu vào của lần gọi mô hình tiếp theo.
OpenAI function calling: các câu hỏi thường gặp
Cái này có hoạt động với Chat Completions API không?
Có, với định dạng tools cũ hơn của Chat Completions, trong đó function nằm trong một đối tượng function và kết quả trả về dưới dạng các message tool. Bản thân function tìm kiếm không thay đổi.
Mô hình có thể đọc một trang mà nó tìm thấy trong một nguồn không?
Thêm một function thứ hai, read_urls, gửi URL tới https://llmwebsearch.com/api/v1/extract. Đọc các trang mà bạn đã có URL tốn 1 credit cho mỗi nhóm 3 trang bắt đầu được trả về kèm nội dung, tối đa 20 URL mỗi lượt gọi; các URL bị từ chối hoặc thất bại không được tính.
Nên dùng mô hình nào?
Bất kỳ mô hình nào hỗ trợ function calling. Hãy thử hai hoặc ba mô hình với câu hỏi của chính bạn: câu trả lời phụ thuộc vào các nguồn cũng như vào mô hình, và một mô hình nhỏ hơn tốn ít chi phí hơn mỗi vòng.
Nguồn (2)
- Function calling — OpenAI API docs (read 2026-10-22)
- Công cụ (OpenAI Agents SDK) — OpenAI Agents SDK docs (read 2026-10-22)