OpenAI / Claude エージェントにリアルタイム Web 検索を 4 ステップで追加する

エージェントの回答を最新情報で裏付けたい?必要なのは 2 つ:LLM 向けスニペットを返す検索 API と、モデルが呼べるツール定義。本記事はこれを 4 ステップで実装する。
要点
- •Step 1:API キーを発行(無料)して curl でエンドポイントを叩く。
- •Step 2:OpenAI / Claude の tool schema を API から取得 — JSON は手書きしない。
- •Step 3:エージェント(OpenAI Assistants、Anthropic Messages、LangChain、n8n)にツール登録。
- •Step 4:tool ハンドラで /api/search/web を呼び、結果をモデルに返す。
なぜこの記事が短いか
「LLM に Web 検索を足す」チュートリアルが長くなるのは、検索 API の SDK や重量級エージェントフレームワークの解説になるから。本記事は違う。仕事は:エンドポイントを選ぶ → ツール登録 → 5 行のハンドラを書く、それだけ。
1無料の API キーを取得してエンドポイントを叩く
apipick.com/dashboard/api-keys でサインアップ。新規アカウントは 100 クレジット無料、クレカ不要。キーを作って:
curl -X POST https://www.apipick.com/api/search/web \
-H "x-api-key: pk_yourkey" \
-H "Content-Type: application/json" \
-d '{"query": "what is retrieval augmented generation"}'整理された ranked リスト(title、URL、snippet)が返る。curl で動くと確認すれば後のデバッグ時間が大幅に減る。
2tool schema を取得(手書きしない)
API Pick は GET /api/search/web/tool-schema でコピペ用 tool schema を提供。OpenAI 関数定義と Claude tool use 定義の両方。
curl https://www.apipick.com/api/search/web/tool-schema結果はキャッシュしてよい — 頻繁には変わらない。関数 schema の手書きはエージェントコードで最もバグりやすい場所(型違い、required 違い、description 欠如)。
3エージェントにツールを登録
OpenAI Assistants
from openai import OpenAI
import requests
client = OpenAI()
schema = requests.get("https://www.apipick.com/api/search/web/tool-schema").json()
assistant = client.beta.assistants.create(
name="Research Agent",
model="gpt-4o",
instructions="Use web_search whenever the user asks about current events or anything that changes after your training cutoff.",
tools=[{"type": "function", "function": schema["openai"]}],
)Anthropic Claude
import anthropic
import requests
schema = requests.get("https://www.apipick.com/api/search/web/tool-schema").json()
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=[schema["claude"]],
messages=[{"role": "user", "content": "Summarise this week's RAG research."}],
)LangChain
from langchain.tools import tool
import requests
@tool
def web_search(query: str) -> dict:
"""Real-time web search. Use for any question that needs current information."""
return requests.post(
"https://www.apipick.com/api/search/web",
headers={"x-api-key": "pk_yourkey"},
json={"query": query},
).json()n8n
HTTP Request ノードを追加:method POST、URL https://www.apipick.com/api/search/web、ヘッダ x-api-key: pk_yourkey、JSON ボディ {"query": "{{ $json.query }}"}。エージェントノードや LLM Chain ノードに繋ぐ。SDK 不要。
4ツール呼び出しを処理
OpenAI Assistants の run が requires_action で止まったら、検索を実行して結果を提出:
import json, time, requests
from openai import OpenAI
client = OpenAI()
KEY = "pk_yourkey"
def run_with_tool(thread_id: str, assistant_id: str):
run = client.beta.threads.runs.create(thread_id=thread_id, assistant_id=assistant_id)
while True:
run = client.beta.threads.runs.retrieve(thread_id=thread_id, run_id=run.id)
if run.status == "requires_action":
outputs = []
for call in run.required_action.submit_tool_outputs.tool_calls:
if call.function.name == "web_search":
args = json.loads(call.function.arguments)
result = requests.post(
"https://www.apipick.com/api/search/web",
headers={"x-api-key": KEY},
json=args,
).json()
outputs.append({"tool_call_id": call.id, "output": json.dumps(result)})
client.beta.threads.runs.submit_tool_outputs(
thread_id=thread_id, run_id=run.id, tool_outputs=outputs,
)
elif run.status in ("completed", "failed", "cancelled", "expired"):
return run
time.sleep(0.5)Anthropic Messages のループも同様 — レスポンスに tool_use ブロックが現れたら API を呼び、次のターンで tool_result ブロックとして返す。
ループを安定させる
- tool description はモデル視点で:「Use this when the user asks about current events, breaking news, or anything that may have changed after your training cutoff.」と書く。「これは Web 検索 API です」とは書かない。
- 同じ会話で同じ query が繰り返されたらハンドラでキャッシュ。検索結果は分単位で安定、同じ会話で 2 回 15 credits 払う必要はない。
- 鮮度が重要なら
start_dateを付ける。「今週のニュース」は日付フィルターなしだと去年の見出しが返ることが多い。
次の一歩
エージェントが検索できるようになったら、次は記事を読ませる。URL 内容抽出 API を 2 つ目のツールとして登録 — 同じ認証、同じ JSON 形式、1 回最大 25 URL。「検索 + 抽出」が最小実用のリサーチエージェント。
よくある質問
Assistants ではなく OpenAI Responses API でも使える?
使える。同じ tool schema を client.responses.create() の tools=[{...}] に渡すだけ。ハンドラの形は同じ:tool_calls をパース、POST /api/search/web を呼び、JSON を返す。
結果をモデルに返す前に整形が必要?
不要。POST /api/search/web は ranked の title + URL + LLM 向け snippet を返す。生 JSON をそのままツール結果として返せばよい。モデルが snippet を引用し URL をリンクする。
エージェントターン 1 回あたりのコストは?
Web 検索 1 回 15 credits($5 / 5,000 で約 $0.015)。1 回ツールを呼ぶ典型的なターンの検索コストは 1 セント未満。コストの大部分は LLM トークン。
モデルがツールを呼ばない場合は?
tool description を具体的に。「Use this for any question that requires current or post-training information」は「web search」よりずっと効く。モデルは「このツールが何をするか」を理解できれば自発的に使う。
国や日付範囲で絞れる?
可。country_code(ISO 3166-1 alpha-2)、start_date / end_date(YYYY-MM-DD)を渡す。モデルに選ばせるなら tool schema にパラメータとして含める、エージェントが固定 locale や鮮度要件を持つならハンドラで直書きでよい。
この記事で使われている API
API Pick の CEO。AI エージェントと LLM ワークフロー向けの本番運用可能な API について執筆。