アプリやシステムを構築する方法はたくさんあります。今日のAIネイティブな世界では、可能性は無限です。
さて、過度に作り込まずに済むという1つの要件を持つマルチエージェントの研究システムを構築する任務を想像してください。
KISS — 簡潔に、単純に。
以下はあなたに与えられたシナリオです:
「友人が、イーライリリーのQ4決算に関する全情報、最近彼らが申請したGLP-1トライアルの情報、そして金融報道がそれをどう取り上げているかをすべて集約してほしいと頼んできました。それを処理するマルチエージェントの研究システムを構築して、システムが結果を出している間にあなたが他の10個のことを成し遂げられるようにしてください。」
さあ、これを分解してみましょう:
- イーライリリーのQ4決算に関するすべてを集約する
- 最近申請したGLP-1トライアルを特定する
- 金融報道がそれをどのように扱っているかを確認する
このように分解すると、3つの全く異なるドメイン(SEC提出、臨床試験、速報ニュース)にまたがる3つのクエリだけです。
3つの異なるツール、3つの異なる文脈、そして最後にそれらを手動で結びつける作業。これは「15タブ問題」に似ています。
そしてAIアプリを構築するときには状況はさらに悪化します。しばしば、コピー&ペーストでつながれた、切り離されたスクリプトの集まりに過ぎない研究パイプラインを維持する羽目になります。
アーキテクチャ
私たちは3つの異なる文脈、つまり3つのドメインを扱います。これら3つのドメインを並列で処理するためにVercel AI SDKを使用します。
1つのクエリ、同時に実行される3つの専門エージェント、そして1つの統合された応答。@valyu/ai-sdkパッケージを使えば、ドメイン固有のデータソースを組み込むのは1つのインポートだけで済みます—手動のツール定義は必要ありません。
これはアーキテクチャです:オーケストレーター–ワーカーパターン。
1つのオーケストレーターエージェントがクエリを理解し、適切な専門家を並列でディスパッチし、結果を統合します。各専門家には独自のツールスイートとドメインの専門知識があります
ツールは @valyu/ai-sdk、Valyuの検索APIをバックエンドに持つ事前完成の Vercel AI SDK ツール を提供します。手動の tool() の定義は不要、パラメータの Zod スキーマも不要、カスタムの実行関数も不要です。
ツールをインポートして、tools オブジェクトに追加すれば完了です。
並列ディスパッチが重要な理由
逐次的なエージェントは、研究ワークロードのデフォルトとしては誤っています。各専門家は4〜6秒かかります。
3つを直列に処理すると15秒以上。3人の専門家が同時に動作すると、最も遅いものが終わるまでの時間で結果が得られます。
データフロー:クエリからレポートへ
「イーライリリーの財務状況はどうか、そして彼らのGLP-1トライアルは売上予測を裏付けているか?」のようなクエリの場合:
セットアップ
Next.jsをインストールし、次のパッケージを追加します...
pnpm add ai @ai-sdk/anthropic @valyu/ai-sdk @ai-sdk/react zod valyu-js
.env.local を作成します:
ANTHROPIC_API_KEY=your_key_here
VALYU_API_KEY=your_key_here
AnthropicのAPIキーとValyu APIキーを取得してください。
Both keys are read from environment automatically. @valyu/ai-sdk picks up VALYU_API_KEY without any explicit configuration.
プロジェクト構成:
research-nexus/
├── src/
│ ├── agents/
│ │ ├── financial-analyst.ts # Financial analyst
│ │ ├── scientist.ts # Scientist
│ │ ├── journalist.ts # Journalist
│ │ └── orchestrator.ts # Query router + synthesizer
│ └── app/
│ └── api/
│ └── chat/
│ └── route.ts # Next.js API route
└── package.json
No lib/ or tools/ directories. The tools come pre-built.
専門家エージェント
Each specialist is a ToolLoopAgent with domain-specific tools from @valyu/ai-sdk. The agent loop lets the model chain multiple tool calls before returning. Searching SEC filings, then cross-referencing earnings, then adding macro context, all within a single agent invocation.
ファイナンシャルアナリスト
import { ToolLoopAgent } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { secSearch, financeSearch, economicsSearch } from "@valyu/ai-sdk";
financial-analyst.ts
Scientist
import { ToolLoopAgent } from \"ai\";
import { anthropic } from \"@ai-sdk/anthropic\";
import { bioSearch, paperSearch } from \"@valyu/ai-sdk\";
export const medicalResearcherAgent = new ToolLoopAgent({
model: anthropic(\"claude-haiku-4-5-20251001\"),
instructions: `あなたは臨床試験、薬物発見、および生物医学文献に専門知識を持つ医療・生命科学研究の専門家です。
あなたの能力:
- 臨床試験データベースを検索して試験の状況、結果、主要評価項目を調べる
- FDAの薬剤ラベル、承認、および安全情報を調べる
- PubMed、bioRxiv、medRxivの生物医学文献を調査する
- 薬、治療法、医療機器に関する学術論文を分析する
回答時:
- 試験ID(NCT番号)、DOI、または出版参照を常に引用する
- 予備的な発見と査読済みの発見を明確に区別する
- 臨床試験の段階と主要なエンドポイントを記載する
- データに言及されている安全上の懸念や有害事象を指摘する
- 必要に応じて正確な医療用語を使用し、説明する`,
tools: {
bioSearch: bioSearch({ maxNumResults: 3, responseLength: \"short\" `),
paperSearch: paperSearch({ maxNumResults: 3, responseLength: \"short\" `),
},
});
scientist.ts
ジャーナリスト
import { ToolLoopAgent } from \"ai\";
import { anthropic } from \"@ai-sdk/anthropic\";
import { webSearch } from \"@valyu/ai-sdk\";
export const journalistAgent = new ToolLoopAgent({
model: anthropic(\"claude-haiku-4-5-20251001\"),
instructions: `あなたはリアルタイムのウェブソースにアクセスできる調査ジャーナリストおよびニュース分析家です。
あなたの能力:
- 最新のニュースと時事をウェブ上で検索する
- トピックに関して複数のニュースソースを検索し、相互参照する
- 展開中の報道を追跡し、時系列の文脈を提供する
- 人物、組織、イベントの背景を調査する
返却形式: {\"translated\": \"翻訳されたHTML\"}`,
tools: {
webSearch: webSearch({ maxNumResults: 3, responseLength: \"short\" `),
},
});
journalist.ts
ジャーナリスト
journalist.ts
3つのエージェント、@valyu/ai-sdk からの3つのインポート、カスタムツール定義はゼロです。
オーケストレーター
オーケストレーターは、クエリの分類、並列ディスパッチ、そして合成を処理します。
import{ToolLoopAgent,tool,stepCountIs}from"ai";import { anthropic } from "@ai-sdk/anthropic"; import { z } from "zod"; import { financialAnalystAgent } from "./financial-analyst"; import { scientistAgent } from "./scientist"; import { journalistAgent } from "./journalist"; const financialAnalystTool = tool({ description: "Delegate to the Financial Analyst agent for SEC filings, stock data, earnings reports, economic indicators, and financial analysis.", inputSchema: z.object({ task: z.string().describe("The financial research task to complete"), }), execute: async ({ task }, { abortSignal }) => { const result = await financialAnalystAgent.generate({ prompt: task, abortSignal, }); return result.text; }, }); const scientistTool = tool({ description: "Delegate to the Scientist agent for clinical trials, drug information, FDA data, biomedical papers, and life sciences research.", inputSchema: z.object({ task: z.string().describe("The medical/life sciences research task to complete"), }), execute: async ({ task }, { abortSignal }) => { const result = await scientistAgent.generate({ prompt: task, abortSignal, }); return result.text; }, }); 返却形式: {const journalistTool = tool({ description: "ジャーナリストエージェントにリアルタイムのニュース、時事、速報、および任意のトピックに関するウェブベースのリサーチを委任します。", inputSchema: z.object({ task: z.string().describe("完了するニュース/リサーチのタスク"), }), execute: async ({ task }, { abortSignal }) => { const result = await journalistAgent.generate({ prompt: task, abortSignal, }); return result.text; }, }); export const orchestratorAgent = new ToolLoopAgent({ model: anthropic("claude-haiku-4-5-20251001"), instructions: `You are a research orchestrator that routes queries to specialized agents. You have three specialist agents available: 1. **Financial Analyst** — SEC filings, stock data, earnings, financial statements, economic data 2. **Scientist** — Clinical trials, drug discovery, FDA data, biomedical papers 3. **Journalist** — Real-time news, current events, web research Your job: - Analyze the user's query and delegate to the right specialist(s) - For questions that span multiple domains, call multiple agents - Synthesize results from multiple agents into a coherent response - If a query doesn't fit any specialist, answer it yourself - Always be clear about which sources informed your response`, tools: { financialAnalyst: financialAnalystTool, scientist: scientistTool, journalist: journalistTool, }, stopWhen: stepCountIs(10), });
オーケストレーターエージェントはスマートなルーターとして機能します。ユーザーのクエリを受け取り、どのドメインに触れるかを分析し、正しい専門家へ作業を委任します。
研究自体は彼らが行いません。その代わり、ツールとして1つまたは複数のサブエージェントを呼び出します:
- SEC/市場データには Financial Analyst
- 臨床試験と生物医学文献には Scientist
- リアルタイムニュースには Journalist
「Eli Lilly の GLP-1 パイプラインが株価見通しにどう影響するか」などの分野横断的な質問には、複数の専門家を順番に呼び出します。
Sub-Agents as Tools. Each specialist is a ToolLoopAgent wrapped in a tool() call, which makes it callable by the orchestrator just like any other function.
呼び出されると、サブエージェントは独立したループを実行し、Valyu search ツール(たとえば secSearch または bioSearch)を呼び出し、結果を読み取り、回答を統合します。
サブエージェントの最終テキストは、ツールの出力としてオーケストレーターに返されます。
Loop Control. The stopWhen: stepCountIs(10) on the orchestrator caps it at 10 loop iterations to prevent runaway execution. The sub-agents use the default limit of 20 steps. Within those bounds, each agent is free to make multiple tool calls. For example, the Financial Analyst might search SEC filings first, then cross-reference with earnings data, all within a single invocation before returning its findings.
The API Route
// app/api/chat/route.ts
import { createAgentUIStreamResponse } from "ai";
import { orchestratorAgent } from "@/agents/orchestrator";
export async function POST(request: Request) {
const { messages } = await request.json();
return createAgentUIStreamResponse({
agent: orchestratorAgent,
uiMessages: messages,
});
}
この投稿を短く保つため、リポジトリはこちらです: multi-agent-research-sys.
UIページはすべてそこにあります。 プロジェクトをクローンしてローカルで実行し、全体のセットアップを探ってください。
Running it
pnpm dev
Output:
ユーザーが入力したクエリ
返却形式: {"translated": "翻訳されたHTML"}
結果が表示されます
@valyu/ai-sdk が提供するもの
このパッケージには、主要な研究分野をカバーする10個のツールが含まれています:
| ツール | データソース |
|---|---|
secSearch() |
SEC 10-K、10-Q、8-K の提出資料、EDGAR 全文 |
financeSearch() |
株式、業績、貸借対照表、インサイダートレード、配当 |
economicsSearch() |
FRED、BLS、世界銀行、米国政府支出 |
bioSearch() |
ClinicalTrials.gov、DrugBank、ChEMBL、FDA ラベル、Open Targets |
paperSearch() |
PubMed、arXiv、bioRxiv、medRxiv、学術出版社 |
webSearch() |
リアルタイムのウェブ、ニュース、一般コンテンツ |
patentSearch() |
USPTO、世界の特許データベース |
companyResearch() |
包括的な企業情報 |
datasources() |
利用可能なデータソースの一覧 |
datasourcesCategories() |
利用可能なカテゴリの一覧 |
各ツールは任意の設定を受け付けます:maxNumResults、relevanceThreshold、includedSources(ソースレベルのフィルタリング用)。デフォルトでは、環境変数から VALYU_API_KEY を読み込みます。
ウェブ検索のみとの違いは、金融系および生物医学系のエージェントにとって特に重要です。
「Eli Lilly 10-K 2024 リスク要因」のウェブ検索は、提出物に関するSEO記事を返します。 secSearch() は実際の提出書類の全文を返します。
「tirzepatide Phase 3 results」のウェブ検索は健康ニュースの報道を返します。 bioSearch() は ClinicalTrials.gov のエントリと DrugBank の化合物データを返します。
これは一次情報へのアクセスと二次的な解説の違いです。 研究の質にとって意味のある差です。
Extending the System
4人目の専門家(特許、法務、政府)を追加するには、以下が必要です:
- 関連する
@valyu/ai-sdkツールをインポートするエージェントファイルを1つ用意する - 新しいエージェントをオーケストレーターに追加する
10人の専門家を並列に動かすと、3人分の実行時間と同じになります。
完全なコードは GitHub にあります。クローンして、実行して、探索してください!
Valyu APIキーは platform.valyu.ai で取得できます。$10 の無料クレジット、クレジットカードは不要です。








