Pydantic AI、WebSearch機能を活用した研究エージェントの実装例を公開
本文の状態
日本語全文を表示中
詳細モードで約10分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
Pydantic Blog
Pydantic Blog は、ネイティブ検索の限界を克服し、Exa の API を活用することで深層調査が可能な研究エージェントを実装する具体的なコード例と戦略を提示している。
AI深層分析を開く2026年8月4日 02:09
AI深層分析
キーポイント
ネイティブ検索の限界と基本実装
Pydantic AI の WebSearch 機能を用いた 10 行程度のコードで基本的な研究エージェントは構築可能だが、これは単なるリンク取得に留まり、深層調査や詳細なページ内容の取得には不十分である。
Exa API を活用した生産レベルの実装
「Exa」は AI エージェント向けに設計された検索エンジンであり、スクレイピングを不要とし、低遅延から深層推論までを一つの API で提供するため、実用的な研究エージェントの基盤として推奨される。
Exa Agent API による完全自動化
計画、サブ検索、ページ読取、合成、引用を含む包括的な調査タスクに対し、Exa のホスト型サービスである Exa Agent API をワンライナーでラップすることで、高度な研究エージェントを構築できる。
サブエージェントによる深層調査の自動化
ExaAgent を能力として追加することで、親エージェントがリサーチャーを雇用したような状態になり、トークンコストやコンテキスト管理は API 側で処理される。
構造化出力による結果の検証
Pydantic モデルを output_schema に指定することで、完了した実行結果が返却される際に検証され、不一致の場合は隠蔽されずに再試行が発生する。
重要な引用
"web search, built for AI agents."
"The agents that make their living reading the web have all quietly settled on the same eyes."
"If the agent that ships production code trusts Exa for its web-facing brain, the research agent you assemble today can too."
"the parent agent gets a researcher on staff, context isolation included"
編集コメントを表示
編集コメント
この記事は、AI エージェントの実用化において検索機能の質がボトルネックとなる現状を指摘し、それを解決する具体的な技術的アプローチを示している。開発者は単にモデルを選定するだけでなく、背後で動作する検索インフラの選定がエージェントの性能を決定づけるという視点を持つべきである。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
Harness Week
これは 5 本立てシリーズの 1 部です。この連載の核心は「あなたは以前、このようなエージェントを構築したことがある」という点にあります。
昨日は構成要素について説明しました。今日はその主張を実際に試す日です。「移行に着手する前に、ベンダーの選択肢を調査できるか?」という問いに対する直感的な答えは「いいえ、それは違うエージェントだ」になるでしょう。しかし、その直感は「エージェント単位で考えている」ことに起因しています。今週は、「部品単位で考える」ことについて解説します。
構築可能な基本形
わずか 10 行のコードで、動作する調査用エージェントが作れます。Pydantic AI のコアには WebSearch という機能が標準搭載されており、これによりモデル自体がネイティブの Web 検索機能を有効にできます。Anthropic、OpenAI、Google、Groq など、主要なプロバイダーはみなこの機能を提供しています。
import logfire
from pydantic import BaseModel
from pydantic_ai import Agent
from pydantic_ai.capabilities import WebSearch
logfire.configure()
logfire.instrument_pydantic_ai()
class Finding(BaseModel):
claim: str
source_url: str
class Report(BaseModel):
summary: str
findings: list[Finding]
agent = Agent(
'anthropic:claude-opus-4-7',
output_type=Report,
capabilities=[WebSearch(allowed_domains=['docs.aws.amazon.com'])],
)
result = agent.run_sync(
'What HA options does RDS for Postgres offer today?'
)小規模な事実確認であれば、この程度で十分です。output_type=Report を指定すれば、回答はすでに検証済みのデータとして返されます。しかし、これには限界があります。ネイティブの Web 検索では、プロバイダーのインデックスに基づいてリンクやスニペットがスコアリングされるだけで、ページ内容の取得ステップや深掘りモード、あるいは研究エージェントに必要な検索制御機能は提供されません。質問が単なる確認を超えたものになったときこそ、本格的な研究エージェントを構築する最速ルートは、既存の棚から選ぶ道ではなくなるのです。
生産環境への最速ルート
研究エージェントの品質は、その検索能力に依存します。多くのエージェントが採用している「青いリンクをスクレイピングして運を天に任せる」ような検索手法こそが、「深掘り調査」という言葉が空回りする原因となっています。ウェブを精読して生計を立てているエージェントたちは、みな静かに同じ検索エンジンにたどり着いています。
Exa のキャッチフレーズはそのまま仕様書です。「AI エージェント向けに構築された Web 検索」。ライブ上の Web を意味的に検索し、スクレイピングの手間なくページ内容を同一の呼び出しで取得できます。低遅延から深層調査までを一つの API でカバーするこの範囲には、クイックルックアップ用の「即時モード」、バランス型検索の「自動モード」、そして構造化出力を伴う多段階処理が必要な質問に対応するための「深層/深層推論モード」が含まれています。コード生成エージェントはこの機能範囲に依存しています。Exa は Cursor のドキュメントやリポジトリ間の検索を支えており、Cognition の共同創設者である Walden Yan 氏は、「Exa が Devin のすべての部分を駆動している」と明言しています。本番環境のコードを納品するエージェントが Web を扱う脳として Exa を信頼しているのであれば、今日あなたが組み立てる研究エージェントも同様に信頼できるはずです。
研究タスクを丸ごと Exa に任せる
究極の活用方法は、研究そのものが問い全体となるケースです。計画立案からサブ検索、ページ閲覧、合成、引用まで、すべてを包括する研究タスクにおいて、Exa はホスト型サービスとして機能します。これが「Exa Agent API」で、ハッチ(harness)はこれをワンライナーのラッパーとして提供しています。
import logfire
from pydantic_ai import Agent
from pydantic_ai_harness.exa import ExaAgent
logfire.configure()
logfire.instrument_pydantic_ai()
agent = Agent(
'anthropic:claude-opus-4-7',
capabilities=[ExaAgent()],
)
result = agent.run_sync(
'Which managed Postgres should we migrate to? Compare pricing, HA, '
'and migration path from RDS across the main contenders. Cite every claim.'
)ExaAgent は exa_agent という 1 つのツールを追加します。親プロセスが問いを渡すと、Exa Agent API がそのインフラに対して多段階の研究パスを実行します(質問の重要性に応じて最大 1 時間まで)。このツール呼び出しは、引用付きの回答が完成するまで待機します。
フォローアップ質問では、previous_run_id を通じて実行コンテキストを保持するため、選定されたベンダーに関する次の問いでもゼロからやり直す必要はありません。構造化出力が必要であれば、output_schema=Report のように Pydantic モデルを渡すことで、完了した実行結果の返却時に検証が行われます。不一致が発生すれば、静かに失敗するのではなくリトライとして表面化します。
研究における「部品リスト」の結論とは、親エージェントがスタッフとして研究者を雇い、コンテキスト分離も含まれた上で、10 万トークン分のソース読込コストは Exa の API 呼び出し側で処理されるという点です。これが、「深層エージェント(deep agents)」という能力インポートによって提供されるサブエージェントの柱であり、組み立ての手間は不要です。
パイラーが効果を発揮する場面での構成
時には構築が必要になることもあります。許可リスト内のソース、モデルがクリアすべき引用基準、実行ごとに蓄積されるノート、チームの実態に即した研究プロセスなどです。その場合こそ、ハネス(harness)の棚が真価を発揮します。
同じ Exa による検索機能ですが、今回は個別のツールとして公開されます。具体的には ExaSearch を介して、web_search は各ヒット結果を最も関連性の高い抜粋と共に返すため、調査コストを抑えられます。また get_page は選択した URL の全文を読み込みます。これら 2 つのツールを一つの shipped な機能に統合する研究戦略に加え、長時間の実行を支える骨格となるハネスの部品群も用意されています。
import logfire
from pydantic import BaseModel
from pydantic_ai import Agent
from pydantic_ai_harness import CodeMode
from pydantic_ai_harness.exa import ExaSearch
from pydantic_ai_backends import ConsoleCapability # filesystem
from pydantic_ai_summarization import ContextManagerCapability # compaction
from pydantic_ai_todo import TodoCapability # planning
logfire.configure()
logfire.instrument_pydantic_ai()
class Finding(BaseModel):
claim: str
source_url: strclass Report(BaseModel):
summary: str
findings: list[Finding]
agent = Agent(
'anthropic:claude-opus-4-7',
output_type=Report,
capabilities=[
CodeMode(),
TodoCapability(),
ConsoleCapability(),
ContextManagerCapability(max_tokens=180_000),
ExaSearch(
include_deep_search=True,
include_domains=['docs.aws.amazon.com', 'planetscale.com', 'neon.tech'],
),
],
)
include_deep_search=True を設定すると、深層検索(deep_search)という 3 つ目のツールが利用可能になります。これは Exa の多段階にわたる深い探索モードを、必要な質問に対して単一呼び出しとして提供する機能です。また、この機能のガイダンスにより、モデルは「いつエスカレーションすべきか」を教わるようになります。include_domains を指定すると、検索範囲をベンダー公式ドキュメントに限定できます。これはモデルが言い訳で回避できないルールです。
タスクリストは 3 時間の実行を質問指向で維持し、ファイルには中間ノートやドラフトが保存されます(圧縮の間隔)。レポート内のすべての主張は、Exa が実際に返した URL に紐付けられています。Logfire で全体を計測すると、1 つのトレースに計画、各サブ検索、そして合成プロセスが記録されます。これが研究者のデバッグ方法です。
#Why this matters
今週の議論を要約したのが、この 3 つのインポート行です。
まずは shipped なものから始めましょう。天井が邪魔になったらレベルアップし、問題の形状が自分自身のものである必要があるならコンポジション(組み合わせ)を選びます。月曜日のエージェントはそのままに、各ステップで 1 つずつ機能を追加し、常に同じパブリック API に応答します。
これが標準ライブラリの役割です。「研究用エージェントを構築する」という行為が、「プロジェクトを始める」ことから「午後の時間を組み立てる」ことに意味を変える地点です。
また、これは前方へのコンポジションでもあります。エージェントがエージェントを構築するプロセスは、実行・学習・再武装のループで完結します。メモをファイルに、計画を TODO に保持する研究ループは、昨日学んだすべてのことを取り込んで再武装し、Exa は常に視界を新鮮に保つ役割を果たします——各サイクルごとにライブ検索を行い、古びたクロールには頼りません。
次に依頼するレポートが、そのエージェントがこれまでに書いた中で最悪のものになるでしょう。
「エージェンツ・ウィーク」は、「 herd(群れ)」に関する議論から始まりました。手動で育てられる数以上のエージェントを運用することになります。それが生き残れる理由は、先ほどご覧いただいた再コンポジションにあります。共有可能で交換可能、かつ検証可能な部品から組み立てられたエージェントは、構造的に家畜のようなものです。一方、独自フレームワークを中心にゼロから構築された特注のエージェントは、かつてペットのような存在でした。
#Getting started
pydantic-ai-slim には WebSearch が最初から搭載されているため、ネイティブ版を利用しても既存のモデルプロバイダーへの支払い以外に追加費用はかかりません。uv add "pydantic-ai-harness[exa]" を実行すれば ExaAgent と ExaSearch が利用可能になり、環境変数 EXA_API_KEY に Exa の API キーを設定するだけで連携が完了します。今回の記事で取り上げる 3 つのエージェントはすべて無料クレジット範囲内で動作可能です。
さらに本格的な構築を進める際は、[codemode] とコミュニティ製のパッケージ(pydantic-ai-backend、summarization-pydantic-ai、pydantic-ai-todo)を組み合わせてください。機能マトリクスでは、公式およびコミュニティ製のパッケージ一覧を管理しており、各項目は GitHub の Issue や PR として公開されています。ここであなたの投票が、次に開発される機能の方向性を決定します。
研究エージェントの導入コストは、単なるインポートと同程度です。必要なのは、データ参照の実装か、ホスト型リサーチャーの利用、あるいは実際に使いたいループを構築するための数時間の作業だけです。残りの週は、より困難な課題への挑戦となります。水曜日はエージェント速度でレビューループが稼働し、木曜日は本格的な計算資源を使用し、金曜日にはエージェントが破損しても許容されるクラウド環境でのテストを行います。
原文を表示
Harness Week
This is part of a five-post series. The thesis is in You've built this agent before.
Yesterday laid out the parts. Today the argument gets a real test: "before we commit to the migration, can it research the vendor options?" The reflex says no, wrong agent. The reflex is thinking in agents. This week is about thinking in parts.
#The basic thing you can build
Ten lines gets you a working research agent. Pydantic AI's core ships WebSearch, a capability that turns on the model's own native web search — Anthropic, OpenAI, Google, and Groq all have one:
import logfire
from pydantic import BaseModel
from pydantic_ai import Agent
from pydantic_ai.capabilities import WebSearch
logfire.configure()
logfire.instrument_pydantic_ai()
class Finding(BaseModel):
claim: str
source_url: str
class Report(BaseModel):
summary: str
findings: list[Finding]
agent = Agent(
'anthropic:claude-opus-4-7',
output_type=Report,
capabilities=[WebSearch(allowed_domains=['docs.aws.amazon.com'])],
)
result = agent.run_sync(
'What HA options does RDS for Postgres offer today?'
)
For a factual lookup with a small blast radius, this is enough, and output_type=Report means the answer already comes back as validated data. But the ceiling is low: native web search returns links and snippets scored by the provider's index and doesn't give you a page-contents step, deep-research mode, or the kind of retrieval control a research agent needs when the question earns more than a lookup. Which is when the fastest path to a production-grade research agent stops passing through the shelf.
#The fastest path to production
A research agent is only as good as its retrieval, and the retrieval most agents get, scrape ten blue links and hope, is the bottleneck that makes "deep research" shallow. The agents that make their living reading the web have all quietly settled on the same eyes.
Exa's tagline is the literal spec: "web search, built for AI agents." Semantic search over the live web with page contents returned in the same call, no scraping step, and a range they describe as low-latency to deep research in one API: an instant mode for the quick lookups, auto for balanced retrieval, and deep/deep-reasoning for questions that earn a multi-step pass with structured outputs. Coding agents live on that range: Exa powers Cursor's search across docs and repos, and Cognition co-founder Walden Yan is on record that "Exa powers all parts of Devin." If the agent that ships production code trusts Exa for its web-facing brain, the research agent you assemble today can too.
#Hand the whole thing to Exa
The superpower version is one capability. When research is the whole question — plan, sub-searches, page reads, synthesis, citations — Exa runs it as a hosted service, the Exa Agent API, and the harness ships it as a one-line wrapper:
import logfire
from pydantic_ai import Agent
from pydantic_ai_harness.exa import ExaAgent
logfire.configure()
logfire.instrument_pydantic_ai()
agent = Agent(
'anthropic:claude-opus-4-7',
capabilities=[ExaAgent()],
)
result = agent.run_sync(
'Which managed Postgres should we migrate to? Compare pricing, HA, '
'and migration path from RDS across the main contenders. Cite every claim.'
)
ExaAgent adds one tool, exa_agent. The parent hands over the question, the Exa Agent API runs a multi-step research pass on their infrastructure (up to an hour if the question earns it), and the tool call defers until the run finishes with a cited answer. Follow-ups keep the run's context via previous_run_id, so a second question about the shortlisted vendors doesn't restart from zero. Want structured output? Pass a Pydantic model as output_schema=Report and the completed run's result is validated on the way back; a mismatch surfaces as a retry instead of silently landing.
This is the parts-list punchline for research: the parent agent gets a researcher on staff, context isolation included, and the hundred thousand tokens spent reading sources land on Exa's side of the API call. That's the sub-agent pillar of "deep agents" delivered as a capability import — no assembly required.
#Compose when the pillars pay off
Sometimes you do need to build: sources you allowlist, a citation bar the model has to clear, notes that accumulate across runs, a research process that fits how your team actually works. Then the harness's shelf earns its keep. Same Exa retrieval, exposed as individual tools this time via ExaSearch — web_search returns each hit with its most relevant excerpts (so surveys stay cheap) and get_page reads a chosen URL in full, both with the research strategy that turns two tools into one shipped inside the capability — plus the harness parts that give a long run its spine:
import logfire
from pydantic import BaseModel
from pydantic_ai import Agent
from pydantic_ai_harness import CodeMode
from pydantic_ai_harness.exa import ExaSearch
from pydantic_ai_backends import ConsoleCapability # filesystem
from pydantic_ai_summarization import ContextManagerCapability # compaction
from pydantic_ai_todo import TodoCapability # planning
logfire.configure()
logfire.instrument_pydantic_ai()
class Finding(BaseModel):
claim: str
source_url: str
class Report(BaseModel):
summary: str
findings: list[Finding]
agent = Agent(
'anthropic:claude-opus-4-7',
output_type=Report,
capabilities=[
CodeMode(),
TodoCapability(),
ConsoleCapability(),
ContextManagerCapability(max_tokens=180_000),
ExaSearch(
include_deep_search=True,
include_domains=['docs.aws.amazon.com', 'planetscale.com', 'neon.tech'],
),
],
)
include_deep_search=True exposes a third tool, deep_search, Exa's multi-step deep mode as a single call for the questions that deserve it, and the capability's guidance grows one sentence to teach the model when to escalate. include_domains narrows retrieval to the vendors' own docs — a rule the model can't reword its way around. The todo list keeps a three-hour run pointed at the question, files hold the notes and the draft between compactions, and every claim in the report traces to a URL Exa actually returned. Instrument the whole thing with Logfire and one trace shows the plan, each sub-search, and the synthesis — which is how you debug a researcher.
#Why this matters
Because it's the week's argument in miniature, told in three lines of imports. Start with what ships. Level up when the ceiling gets in the way. Compose when the shape of the problem needs to be yours. Same agent from Monday all the way down, picking up one capability at each step, always answering to the same public API. That's what a standard library is: the point where "build a research agent" stops meaning "start a project" and starts meaning "compose an afternoon."
It also composes forward. When agents build agents ends on loops that run, learn, and re-arm; a research loop that keeps its notes in files and its plan in todos re-arms with everything it learned yesterday, and Exa is the part that keeps its eyes fresh — live search each cycle, not a crawl that ages. The report you commission next is the worst one it will ever write.
Agents Week opened with an argument about herds: you'll run more agents than you can hand-raise. The reason that's survivable is the recomposition you just watched: agents assembled from shared, swappable, inspectable parts are cattle by construction. The bespoke agent, the one built from scratch around a private framework, was always the pet.
#Getting started
pydantic-ai-slim already carries WebSearch, so the native version costs nothing more than the model provider you're already paying. uv add "pydantic-ai-harness[exa]" puts both ExaAgent and ExaSearch on the shelf, and an Exa API key in EXA_API_KEY connects them — the free credits cover all three agents in this post. Layer in [codemode] and the community packages (pydantic-ai-backend, summarization-pydantic-ai, pydantic-ai-todo) when you're ready to compose the deeper build. The capability matrix tracks the rest of the parts list, first-party and community, and every row is an issue or PR where your vote steers what gets built next.
A research agent for the cost of an import — a lookup, a hosted researcher, or an afternoon spent composing the loop you actually want. The rest of the week is the same move on harder ground: the review loop running at agent speed Wednesday, real compute Thursday, then a cloud the agent is allowed to break Friday.
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み