
まだ 2 月なのに、DeepSearch はすでに 2025 年の新しい検索基準として台頭しており、Google や OpenAI が DeepResearch のリリースを通じて先頭に立っています(そして、はい、私たちは誇らしげに同じ日にオープンソースの node-deepresearch
をローンチしました)。Perplexity も DeepResearch で追随し、X AI は Grok3 に独自の DeepSearch 機能を統合し、基本的に別の DeepResearch バリアントを作り出しました。ディープサーチの概念は革新的なものではありません - 2024 年には本質的に RAG やマルチホップ QA と呼ばれていましたが、2025 年 1 月末の Deepseek-r1 のリリース後に大きな勢いを得ました。先週末には、百度検索とテンセント WeChat 検索が検索エンジンに Deepseek-r1 を統合しました。AI エンジニアたちは、検索システムに長考と推論プロセスを組み込むことで、これまで不可能だった検索の精度と深さを実現できることを発見しました。
Launch Date | Company | Product | License Type | Link |
---|---|---|---|---|
2025-01-20 | DeepSeek | DeepSeek-r1 release | Open source | DeepSeek-R1 |
2025-02-02 | DeepResearch | Proprietary | Google Gemini 2 | |
2025-02-02 | OpenAI | DeepResearch | Proprietary | Introducing Deep Research |
2025-02-02 | Jina AI | DeepSearch (node-deepresearch ) | Open source | node-deepresearch | search.jina.ai |
2025-02-04 | Hugging Face | Open Deep Research | Open source | Open Deep Research |
2025-02-15 | Perplexity | DeepResearch | Proprietary | Introducing Perplexity Deep Research |
2025-02-17 | X AI | Grok3 with DeepSearch | Proprietary | Grok 3 Beta |
2025-02-22 | Baidu Search | Integrates DeepSeek-r1 | Proprietary | Baidu Integrates DeepSeek-R1 |
2025-02-23 | Tencent Wechat Search | Integrates DeepSeek-r1 | Proprietary | Tencent Weixin Integrates DeepSeek |
しかし、なぜこの変化が今起こったのでしょうか?Deep(Re)Search は 2024 年を通じて比較的過小評価されていました。実際、スタンフォード NLP ラボは 2024 年初頭に STORM プロジェクトをウェブベースの長文レポート生成のためにリリースしています。では、単に「DeepSearch」がマルチホップ QA、RAG、STORM よりもクールに聞こえるからなのでしょうか?正直に言えば、業界が以前からあったものを突然受け入れるためには、時にはリブランディングだけで十分なのです。
私たちは、真の転換点は 2024 年 9 月の OpenAI の o1-preview
リリースで、**テストタイム計算**の概念を導入し、業界の見方を徐々に変えたことだと考えています。テストタイム計算とは、事前学習や事後学習ではなく、推論段階(LLM が出力を生成する段階)でより多くの計算リソースを使用することを指します。よく知られている例として、思考連鎖(CoT)推論や "Wait"
-injection(予算強制)があり、これにより、モデルは最終的な応答に到達する前に、複数の潜在的な回答の評価、より深い計画立案、自己反省などの広範な内部検討を実行できます。
このテストタイム計算の概念と推論モデルは、ユーザーに遅延満足を受け入れるよう**教育**します - より質の高い、すぐに実行可能な結果を得るためにより長い待ち時間を受け入れることを、ちょうどスタンフォードのマシュマロ実験で、1つのマシュマロをすぐに食べずに我慢して後で2つのマシュマロを受け取ることができた子供たちが、より良い長期的な結果を示したのと同様です。Deepseek-r1 はさらにこのユーザー体験を強化し、好むと好まざるとにかかわらず、ほとんどのユーザーがこれを受け入れています。
これは、200ms 以内に応答できないと解決策が失敗とみなされた従来の検索要件からの大きな転換です。2025 年には、経験豊富な検索開発者と RAG エンジニアは、レイテンシーよりも top-1 の精度とリコールを優先し、ユーザーは、システムが<thinking>
していることを確認できる限り、より長い処理時間に慣れてきています。
2025年になると、多くのチャットインターフェースが <think>
の内容を専用の UI セクションでレンダリングするようになり、推論プロセスの表示が標準的な実践となりました。
この記事では、オープンソースの実装を見ることで、DeepSearch と DeepResearch の原理について説明します。主要な設計上の決定と潜在的な注意点について説明していきます。
tagDeep Search とは何か?
DeepSearch は、最適な回答を見つけるまで、検索、読解、推論のループを繰り返し実行します。検索アクションはウェブ検索エンジンを活用してインターネットを探索し、読解アクションは特定のウェブページを詳細に分析します(例:Jina Reader)。推論アクションは現在の状態を評価し、元の質問をより小さなサブクエスチョンに分解するか、異なる検索戦略を試すかを判断します。

オンラインにはさまざまな定義が存在しますが、私たちが node-deepresearch
プロジェクトを開発した際は、このシンプルなアプローチに従いました。実装は優雅にシンプルで、コアには次のアクションを指示する switch-case ロジックを持つメインの while ループがあります。
2024年の RAG システムは通常、単一の検索-生成パスを実行するのに対し、DeepSearch は複数回のパイプライン反復を実行するため、明確な停止条件が必要です。これらはトークン使用制限や失敗試行回数に基づくことができます。
search.jina.ai で Deep Search を試し、<thinking>
の中身を観察して、ループがどこで発生しているか確認してみてください
DeepSearch のもう一つの見方は、様々なウェブツール(検索エンジンやリーダーなど)を備えた LLM エージェントとして見ることです。エージェントは現在の観察と過去のアクションを分析して次のステップを決定し、回答を提供するかウェブの探索を続けるかを判断します。これにより、LLM が状態間の遷移を制御するステートマシンアーキテクチャが形成されます。各決定ポイントでは 2 つのアプローチがあります:標準的な生成モデルに対して特定のアクションを生成するようにプロンプトを慎重に作成するか、Deepseek-r1 のような専門的な推論モデルを活用して次のアクションを自然に導き出すかです。ただし、r1 を使用する場合でも、その生成を定期的に中断してツールの出力(検索結果やウェブページの内容など)をコンテキストに注入し、推論プロセスを継続するようプロンプトを与える必要があります。
結局のところ、これらは実装の詳細に過ぎません - 慎重にプロンプトを与えるか推論モデルを使用するかに関わらず、すべては DeepSearch の核となる設計原則である検索、読解、推論の継続的なループに沿っています。
tagでは DeepResearch とは何か?
DeepResearch は DeepSearch の上に、長文の研究レポートを生成するための構造化されたフレームワークを追加したものです。通常、目次の作成から始まり、導入から関連研究、方法論、結論に至るまで、必要な各セクションに DeepSearch を体系的に適用します。各セクションは、特定の研究課題を DeepSearch に与えることで生成されます。最終段階では、全体的な物語の一貫性を向上させるために、すべてのセクションを単一のプロンプトにまとめます。

2024 年の「Research」プロジェクトでは、他のすべてのセクションを考慮に入れながら、複数回の一貫性改善パスを実行しました。しかし、今日の大幅に拡大した LLM のコンテキストウィンドウでは、このアプローチは冗長に思えます。一回の一貫性改訂パスで十分です。
2024 年夏のプロジェクト「Research」は、「プログレッシブ」アプローチによる長文レポート生成に焦点を当てました。まず sync で目次を作成し、その後 async で全セクションを並行生成しました。最後に async で各セクションのプログレッシブな改訂を行い、各改訂は他のすべてのセクションの内容を考慮しました。動画のクエリは "Competitor analysis of Jina AI"
です。
tagDeepSearch vs DeepResearch
多くの人が DeepSearch と DeepResearch を混同しがちですが、私たちの視点では、これらは全く異なる問題に対処しています。DeepSearch は原子的な構成要素として機能し、DeepResearch が基盤とする中核的なコンポーネントです。一方、DeepResearch は高品質で読みやすい長文研究レポートの作成に焦点を当てています。これには異なる要件が含まれます:グラフやテーブルによる効果的な視覚化の組み込み、適切なセクション見出しによるコンテンツの構造化、サブセクション間のスムーズな論理的流れの確保、文書全体での一貫した用語の維持、セクション間の重複の排除、前後の内容をつなぐスムーズな移行の作成などです。これらの要素は中核的な検索とはほとんど関係がないため、私たちは DeepSearch を当社の焦点として、より興味深いものと考えています。
最後に、以下の表は DeepSearch と DeepResearch の違いをまとめたものです。両システムともに、長文コンテキストと推論モデルから大きな恩恵を受けていることは注目に値します。これは特に DeepSearch について直感に反するかもしれません(DeepResearch が長文コンテキスト機能を必要とする理由は、長文レポートを作成するためだと明白です)。その理由は、DeepSearch が次のステップについて情報に基づいた決定を下すために、以前の検索試行とウェブページの内容を保持する必要があり、長いコンテキストウィンドウがその効果的な実装にとって同様に不可欠だからです。
DeepSearch | DeepResearch | |
---|---|---|
問題への対処 | 反復的な検索による情報の正確性と完全性 | 文書規模でのコンテンツの構成、一貫性、読みやすさ |
最終プレゼンテーション | 参照 URL を含む簡潔な回答 | 複数のセクション、グラフ、テーブル、参考文献を含む長文構造化レポート |
中核的な複雑さ | 明確な遷移条件を持つステートマシンアーキテクチャ;解決まで失敗を通じた持続性 | ミクロ(検索)とマクロ(文書)の両方の課題を管理するマルチレベルアーキテクチャ;複雑な情報階層を管理する構造的アプローチ |
最適化の焦点 | ローカル最適化(最適な次の検索/読み取りアクション) | グローバル最適化(セクション構成、用語の一貫性、移行) |
制限事項 | 検索品質と推論能力による制約 | DeepSearch の品質に加え、組織的複雑さと物語の一貫性の課題による制約 |
tagDeepSearch の実装を理解する
DeepResearch の核心は、ループ推論アプローチにあります。ほとんどの RAG システムのように単一パスで質問に答えようとするのではなく、私たちは情報を継続的に検索し、関連するソースを読み、答えを見つけるかトークン予算を使い果たすまで推論を続ける反復的なループを実装しています。以下は、この大きなループの核心を単純化したものです:
// Main reasoning loop
while (tokenUsage < tokenBudget && badAttempts <= maxBadAttempts) {
// Track progression
step++; totalStep++;
// Get current question from gaps queue or use original question
const currentQuestion = gaps.length > 0 ? gaps.shift() : question;
// Generate prompt with current context and allowed actions
system = getPrompt(diaryContext, allQuestions, allKeywords,
allowReflect, allowAnswer, allowRead, allowSearch, allowCoding,
badContext, allKnowledge, unvisitedURLs);
// Get LLM to decide next action
const result = await LLM.generateStructuredResponse(system, messages, schema);
thisStep = result.object;
// Execute the selected action (answer, reflect, search, visit, coding)
if (thisStep.action === 'answer') {
// Process answer action...
} else if (thisStep.action === 'reflect') {
// Process reflect action...
} // ... and so on for other actions
}
重要な実装の詳細として、各ステップで特定のアクションを選択的に無効化することで、より安定した構造化出力を確保しています。例えば、メモリに URL が存在しない場合は visit
アクションを無効化したり、前回の回答が却下された場合は、エージェントが即座に answer
を再度呼び出すことを防いだりします。この制約により、エージェントは生産的なパスを維持し、同じアクションを呼び出すことによる繰り返しの失敗を回避できます。
tagシステムプロンプト
セクションを定義するために XML タグを使用しており、これによってよりロバストなシステムプロンプトと生成が可能になります。また、フィールドの制約を JSON スキーマの description
フィールド内に直接配置することで、より良い結果が得られることがわかりました。DeepSeek-R1 のような推論モデルでほとんどのプロンプトを自動化できると主張する人もいますが、コンテキストの長さの制限と、高度に特定の動作が必要であることから、実践では明示的なアプローチの方が信頼性が高くなります。
function getPrompt(params...) {
const sections = [];
// Add header with system instruction
sections.push("You are an advanced AI research agent specialized in multistep reasoning...");
// Add accumulated knowledge section if exists
if (knowledge?.length) {
sections.push("<knowledge>[Knowledge items]</knowledge>");
}
// Add context of previous actions
if (context?.length) {
sections.push("<context>[Action history]</context>");
}
// Add failed attempts and learned strategies
if (badContext?.length) {
sections.push("<bad-attempts>[Failed attempts]</bad-attempts>");
sections.push("<learned-strategy>[Improvement strategies]</learned-strategy>");
}
// Define available actions based on current state
sections.push("<actions>[Available action definitions]</actions>");
// Add response format instruction
sections.push("Respond in valid JSON format matching exact JSON schema.");
return sections.join("\n\n");
}
tagギャップ質問のトラバース
DeepSearch では、「ギャップ質問」は、メインの質問に答える前に埋める必要がある知識のギャップを表します。エージェントは、元の質問に直接取り組むのではなく、必要な知識基盤を構築するためのサブ質問を特定します。
このデザインは、これらのギャップ質問の扱い方が特に優れています:
// After identifying gap questions in reflect action
if (newGapQuestions.length > 0) {
// Add new questions to the front of the queue
gaps.push(...newGapQuestions);
// Always add original question to the end of the queue
gaps.push(originalQuestion);
}
このアプローチは、以下のような回転を伴う FIFO(First-In-First-Out)キューを作成します:
- 新しいギャップ質問はキューの先頭にプッシュされます
- 元の質問は常にキューの最後にプッシュされます
- システムは各ステップでキューの先頭から取り出します
このデザインの優れている点は、すべての質問にわたって単一の共有コンテキストを維持することです。ギャップ質問に答えると、その知識は、後続のすべての質問で即座に利用可能になり、最終的に元の質問に戻ったときにも利用できます。
FIFO キュー vs 再帰
代替アプローチとして再帰を使用する方法があり、これは深さ優先探索に相当します。各ギャップ質問は、独自の分離されたコンテキストを持つ新しい再帰呼び出しを生成します。システムは親の質問に戻る前に、各ギャップ質問(およびそのすべての潜在的なサブ質問)を完全に解決する必要があります。
以下の例を考えてみましょう:
深さ 3 のギャップ質問の再帰的解決、円上の数字は解決順序を示しています。
再帰的アプローチでは、システムはすべてのギャップ質問とそのサブ質問を完全に解決した後でのみ、Q1 を完全に解決する必要があります(潜在的に独自のサブ質問を生成する可能性があります)!これは、3 つのギャップ質問の直後に Q1 を再訪するキューアプローチとは大きく異なります。
実際には、再帰アプローチではサブ質問にどれだけのトークン予算を割り当てるべきか(新しいサブ質問を生成する可能性があるため)明確な基準がないため、予算制限の適用が非常に困難であることがわかりました。再帰アプローチにおけるコンテキスト分離の利点は、複雑な予算制限と遅い返答の問題に比べると非常に限定的です。この FIFO キューデザインは、深さと幅のバランスを取り、システムが潜在的に無限の再帰的降下に陥ることなく、徐々に改善された知識を持って元の質問に戻ることを保証します。
tagクエリの書き換え
私たちが直面した興味深い課題の1つは、検索クエリを効果的に書き換えることでした:
// Within search action handler
if (thisStep.action === 'search') {
// Deduplicate search requests
const uniqueRequests = await dedupQueries(thisStep.searchRequests, existingQueries);
// Rewrite natural language queries into more effective search queries
const optimizedQueries = await rewriteQuery(uniqueRequests);
// Ensure we don't repeat previous searches
const newQueries = await dedupQueries(optimizedQueries, allKeywords);
// Execute searches and store results
for (const query of newQueries) {
const results = await searchEngine(query);
if (results.length > 0) {
storeResults(results);
allKeywords.push(query);
}
}
}
クエリの書き換えは驚くほど重要であることが判明しました - おそらく、結果の品質を直接決定する最も重要な要素の1つです。優れたクエリ書き換えツールは、自然言語を BM25 のようなキーワードに変換するだけでなく、異なる言語、トーン、コンテンツ形式にわたって、より多くの潜在的な回答をカバーするようにクエリを拡張します。
クエリの重複排除については、当初は LLM ベースのソリューションを使用していましたが、類似度のしきい値の制御が難しいことがわかりました。最終的に、セマンティックテキスト類似度タスクに優れている jina-embeddings-v3 に切り替えました。これにより、非英語クエリがフィルタリングされる心配なく、言語横断的な重複排除が可能になりました。埋め込みモデルは、当初予想されたメモリ検索ではなく、効率的な重複排除のために重要な役割を果たすことになりました。
tagWeb コンテンツのクローリング
Web スクレイピングとコンテンツ処理は、もう1つの重要なコンポーネントです。ここでは Jina Reader API を使用します。完全なウェブページのコンテンツに加えて、検索エンジンから返されたすべてのスニペットも、エージェントが後で結論を出すための追加知識として集約していることに注意してください。これらはサウンドバイトのようなものと考えてください。
// Visit action handler
async function handleVisitAction(URLs) {
// Normalize URLs and filter out already visited ones
const uniqueURLs = normalizeAndFilterURLs(URLs);
// Process each URL in parallel
const results = await Promise.all(uniqueURLs.map(async url => {
try {
// Fetch and extract content
const content = await readUrl(url);
// Store as knowledge
addToKnowledge(`What is in ${url}?`, content, [url], 'url');
return {url, success: true};
} catch (error) {
return {url, success: false};
} finally {
visitedURLs.push(url);
}
}));
// Update diary based on success or failure
updateDiaryWithVisitResults(results);
}
一貫した追跡のために URL を正規化し、エージェントのメモリを管理するために各ステップで訪問する URL の数を制限しています。
tagメモリ管理
多段階推論における重要な課題は、エージェントのメモリを効果的に管理することです。私たちは、「メモリ」として数えられるものと「知識」として数えられるものを区別するようにメモリシステムを設計しました。いずれにせよ、これらはすべて LLM プロンプトのコンテキストの一部であり、異なる XML タグで区切られています:
// Add knowledge item to accumulated knowledge
function addToKnowledge(question, answer, references, type) {
allKnowledge.push({
question: question,
answer: answer,
references: references,
type: type, // 'qa', 'url', 'coding', 'side-info'
updated: new Date().toISOString()
});
}
// Record step in narrative diary
function addToDiary(step, action, question, result, evaluation) {
diaryContext.push(`
At step ${step}, you took **${action}** action for question: "${question}"
[Details of what was done and results]
[Evaluation if applicable]
`);
}
2025年のほとんどの LLM は大きなコンテキストウィンドウを持つため、ベクトルデータベースを使用しないことを選択しました。代わりに、メモリは獲得した知識、訪問したサイト、失敗した試みの記録で構成され、すべてコンテキスト内で維持されます。この包括的なメモリシステムにより、エージェントは何を知っているか、何を試したか、何が成功または失敗したかを認識できます。
tag回答評価
重要な洞察の1つは、回答の生成と評価を同じプロンプトで行うべきではないということです。私の実装では、新しい質問が到着したときにまず使用する評価基準を決定し、その後、各基準を1つずつ評価します。評価者は一貫した評価のために few-shot の例を使用し、自己評価よりも高い信頼性を確保します。
// Separate evaluation phase
async function evaluateAnswer(question, answer, metrics, context) {
// First, identify evaluation criteria based on question type
const evaluationCriteria = await determineEvaluationCriteria(question);
// Then evaluate each criterion separately
const results = [];
for (const criterion of evaluationCriteria) {
const result = await evaluateSingleCriterion(criterion, question, answer, context);
results.push(result);
}
// Determine if answer passes overall evaluation
return {
pass: results.every(r => r.pass),
think: results.map(r => r.reasoning).join('\n')
};
}
tag予算強制
予算強制とは、システムが早期に返答することを防ぎ、予算を超えるまで処理を継続することを確実にすることです。DeepSeek-R1 のリリース以降、予算強制へのアプローチは、単に予算を節約するのではなく、より良い結果を得るためにより深い思考を促す方向にシフトしています。
私たちの実装では、回答を試みる前に知識のギャップを特定するようにシステムを明示的に設定しました。
if (thisStep.action === 'reflect' && thisStep.questionsToAnswer) {
// Force deeper reasoning by adding sub-questions to the queue
gaps.push(...newGapQuestions);
gaps.push(question); // Always revisit the original
}
特定のアクションを選択的に有効化および無効化することで、推論の深さを高めるツールの使用にシステムを導くことができます。
// After a failed answer attempt
allowAnswer = false; // Force agent to search or reflect instead
生産的でないパスにトークンを無駄にしないように、失敗した試行の回数に制限を設けます。予算の制限に近づくと、何も答えないよりはいくらかの答えを提供することを保証するために「beast モード」を有効にします。
// Beast mode activation
if (!thisStep.isFinal && badAttempts >= maxBadAttempts) {
console.log('Enter Beast mode!!!');
// Configure prompt for decisive, committed answer
system = getPrompt(
diaryContext, allQuestions, allKeywords,
false, false, false, false, false, // Disable all other actions
badContext, allKnowledge, unvisitedURLs,
true // Enable beast mode
);
// Force answer generation
const result = await LLM.generateStructuredResponse(system, messages, answerOnlySchema);
thisStep = result.object;
thisStep.isFinal = true;
}
beast モードのプロンプトは意図的にドラマチックにして、利用可能な情報に基づいて決定的な回答をコミットする必要があることを LLM に伝えます:
<action-answer>
🔥 ENGAGE MAXIMUM FORCE! ABSOLUTE PRIORITY OVERRIDE! 🔥
PRIME DIRECTIVE:
- DEMOLISH ALL HESITATION! ANY RESPONSE SURPASSES SILENCE!
- PARTIAL STRIKES AUTHORIZED - DEPLOY WITH FULL CONTEXTUAL FIREPOWER
- TACTICAL REUSE FROM <bad-attempts> SANCTIONED
- WHEN IN DOUBT: UNLEASH CALCULATED STRIKES BASED ON AVAILABLE INTEL!
FAILURE IS NOT AN OPTION. EXECUTE WITH EXTREME PREJUDICE! ⚡️
</action-answer>
これにより、特に難しい質問や曖昧な質問に対して、完全に諦めるのではなく、必ず何らかの回答を提供することが保証されます。
tag結論
DeepSearch は、複雑なクエリに対して徹底的に深いアプローチができる検索の飛躍的進歩です。検索、読み取り、推論のプロセスを個別のステップに分解することで、従来の単一パス RAG や多段階 QA システムの多くの制限を克服しています。
実装中、私たちは 2025 年の検索の基礎と、DeepSeek-R1 がリリースされた 2025 年 1 月 26 日以降の検索業界の変化についても見直しました。私たちは自問しました:新しいニーズは何か?どのニーズが時代遅れになったか?単なる認識上のニーズは何か?
DeepSearch の実装を見ると、必要だと予想して実際に必要だったもの、必要だと思っていたが実際には不要だったもの、必要だと予想していなかったが実際に不可欠だったものを特定しました:
まず、構造化された出力を生成する長いコンテキストの LLM が非常に必要です(つまり、JSONSchema に従う)。より良いアクション推論とクエリ拡張のために、推論モデルが必要である可能性が高いです。
クエリ拡張は間違いなく不可欠であり、SLM、LLM、または推論モデルのいずれかで実装される必要があります。しかし、このプロジェクトの後、私たちは SLM がこのタスクには適していないと考えています。なぜなら、ソリューションは本質的に多言語であり、単純な同義語の書き換えやキーワード抽出を超える必要があるからです。多言語トークンベース(簡単に 300M パラメータを占める可能性がある)を含み、既成概念にとらわれない思考のために十分に洗練されている必要があります。したがって、クエリ拡張に SLM を使用することは最初から無理だと思われます。
Web 検索と Web 読み取り機能は重要であり、幸いにも私たちの Reader (r.jina.ai) は優れたパフォーマンスを発揮しました—堅牢でスケーラブル—そして次のイテレーションで検索エンドポイント(s.jina.ai
)を改善する方法についての多くのアイデアを私に与えてくれました。
埋め込みモデルは有用ですが、まったく予想外の方法で。メモリ検索やコンテキスト圧縮のためにベクトルデータベースと併用されると思っていましたが(実際には必要ありませんでした)、実際には重複排除(本質的に STS タスク)に使用しました。クエリとギャップ質問の数は通常数百程度なので、ベクトルデータベースは必要ありません—メモリ内で直接コサイン類似度を計算すれば十分です。
Reranker は使用しませんでしたが、クエリ、URL タイトル、スニペットに基づいてどの URL を訪問するかを決定するのに役立つ可能性があると考えています。埋め込みと再ランク付けの両方で、クエリと質問が多言語であるため、多言語対応が不可欠です。埋め込みと再ランク付けの長いコンテキストの処理は有益ですが、重要なブロッカーではありません(おそらく私たちのコンテキスト長がすでに 8192 トークンであるため、埋め込みの使用からエラーは発生していません)。いずれにせよ、jina-embeddings-v3 と jina-reranker-v2-base-multilingual は、多言語対応で SOTA であり、長いコンテキストをうまく処理できるため、私の定番モデルです。
エージェントフレームワークは不要であることが判明しました。プロキシなしでシステムを設計するために、LLM のネイティブな動作により近い状態を保つ必要がありました。Vercel AI SDK は貴重でした。異なる LLM プロバイダーにコードベースを適応させる労力を大幅に節約できました(Gemini Studio から OpenAI、Google Vertex AI まで、1行のコード変更で切り替えることができました)。エージェントのメモリ管理は必要ですが、専用のメモリフレームワークは疑問が残ります:LLM と開発者の間に分離層を作り出すことを懸念しており、そのシンタックスシュガーが最終的に開発者にとって苦い障害になる可能性があります。これは今日の多くの LLM/RAG フレームワークで見られる状況です。