AnythingLLMでDeep Research風の調査を試した結果:Tool Callと出典取得は安定するのか

AnythingLLMには、Web検索やWebスクレイピングなどをAgentのToolとして使う仕組みがあります。

では、ローカルLLMとAnythingLLMを組み合わせれば、ChatGPTのDeep Researchのように、複数のWeb情報源を調べ、出典を示しながら調査結果を整理できるのでしょうか。

今回は、AnythingLLMのWeb Browsingを使い、Gemma 4の複数モデルで同じ調査Promptを実行しました。

先に結論を書くと、AnythingLLMで検索結果Citation付きのResearch Draftを作ることはできました。

ただし、Tool Call: と表示されても、AnythingLLMのUIログ上でTool解決や検索Providerの呼び出しを確認できないケースがありました。さらに、同じモデル・同じPromptでも、UIログと検索結果Citationが残る場合と残らない場合がありました。

特に重要だったのは、AnythingLLMに登録されている正式なTool名が web-browsing である一方、モデルが web_browsing という異なる名前を生成する試行があったことです。

この場合、Web検索を行おうとした表示は出るものの、is executingUsing DuckDuckGo、検索結果件数のUIログや検索結果Citationは残りませんでした。

なお、本記事で「Tool実行を確認した」と書く場合、それは次のUIログを確認したという意味です。

@agent is executing `web-browsing` tool
@agent: Using DuckDuckGo to search for "..."
@agent: I found 10 results

サーバーログ、HTTPトレース、DuckDuckGo側の記録を保存して外部リクエストを直接確認したわけではありません。

今回確認したかったこと

今回の目的は、単に「AnythingLLMでWeb検索できるか」を確認することではありません。

確認したかったのは、ローカルLLMをResearch Workflowとして使ったとき、次の工程を後から検証できる形で残せるかです。

  1. どの検索クエリを使ったか
  2. どのToolを呼び出したか
  3. AnythingLLMのUIログ上でTool解決とProvider呼び出しを確認できるか
  4. どの検索結果URLがCitationとして残ったか
  5. どのsourceを根拠として使ったか
  6. 検索結果の要約情報と本文確認済みの情報を分離できたか
  7. 未確認情報と仮説を分離できたか
  8. 同じ条件で再現できるか

つまり、構造化された回答が出れば成功、とは考えていません。

重要なのは、何を検索し、どのToolが呼び出され、どの検索結果を根拠候補として使い、何を結論づけたかを確認できることです。

以前の記事では、Open WebUIとAnythingLLMを比較し、Web検索付きの回答を作れることと、検証可能なResearch Artifactを作れることは別だと整理しました。

今回はAnythingLLMに絞り、モデル変更によってResearch Draftの内容とTool Callingの再現性がどう変わるかを確認しました。

Research Draft、Verifiable Draft、Research Artifactの違い

本記事では、検証可能性が高くなる3段階として整理します。

  1. 調査結果の形を整えた下書き(Research Draft)
  2. 検索や出典の履歴を追える下書き(Verifiable Draft)
  3. 根拠本文まで確認できる調査成果物(Research Artifact)

調査結果の形を整えた下書き(Research Draft)

  • 調査結果が構造化されている
  • URLやsource候補がある
  • 根拠と仮説が整理されている
  • knowledge gapsや追加検索案がある

この段階では、表示されたsourceが実際のTool実行から得られたものか、本文まで確認したものかは保証されません。

検索や出典の履歴を追える下書き(Verifiable Draft)

Research Draftに加えて、次の一部を後から確認できます。

  • Tool Callに表示された名前
  • 検索クエリ
  • is executing などのTool実行UIログ
  • 検索Provider名
  • 検索結果件数
  • 検索結果URLと検索結果の要約情報を使ったCitation

今回の成功試行は、この段階に部分的に到達しました。

Research Artifact

  • Tool CallとTool Responseが保存されている
  • 取得したURLと本文取得の成否が分かる
  • レポート内の主張が、出典本文の具体的な記述と対応している
  • 検索結果の要約情報と、本文確認済みの根拠が明確に分かれている
  • 再実行条件が残っている
  • 人間による確認結果が記録されている

今回の評価では、見た目が整っているだけではResearch Artifactとは扱いません。

また、モデル自身が出力するQuality ReviewやOverall Assessmentも検証対象です。公開前の補助確認では、すべてのsourceがsnippet_only、またはTool実行を確認できない状態でも、モデルが「Research Artifactとして扱える」と判定するケースがありました。自己評価が付いていること自体は、Tool実行や本文確認の証拠にはなりません。

検証環境

主な検証環境は次の通りです。

項目内容
AnythingLLMv1.15.0
Ollamav0.32.5
検索ProviderDuckDuckGo
Intelligent Tool SelectionON
Web BrowsingON
RAG文書なし
実行環境MacBook Air M5 / メモリ32GB

AnythingLLM、Ollama、検索Provider、Workspace設定、調査テーマ、出力形式は原則として固定しました。

変更したのは主にモデルです。Tool名の問題が見つかった後は、一部の試行でPrompt冒頭に正式なTool名を追加しました。

実験ごとの条件と試行結果

gemma4:12bgemma4:12b-it-q4_K_M は別タグとして記録します。実験07は同じ条件で2回実行したため、別試行として掲載します。

実験Model tagTool名ヒントTool Call表示Tool実行・Provider呼び出しをUIログで確認検索結果Citation主な観測
01gemma4:12bなしweb_browsingいいえなしプレースホルダーsourceと未確認情報を生成
02gemma4:12bなしweb_browsingいいえなし実験01と同種の失敗を再現
03gemma4:12b-it-q4_K_Mなし検索風の構造化出力。成功したTool Callは未確認いいえなしプレースホルダーsourceと裏付けのない情報を生成
04gemma4:26bなしweb-browsingはいあり最も整理されたDraft。ただしURL誤記・省略、source type誤分類あり
05gemma4:e4b-it-q4_K_Mなしweb-browsingはいあり検索結果URL、根拠、仮説を構造化
06gemma4:12b-it-q4_K_Mありweb-browsingはいありヒントありで成功
07-1gemma4:12b-it-q4_K_Mありweb-browsingはいあり同じヒントあり条件で成功
07-2gemma4:12b-it-q4_K_Mありweb_browsingいいえなし同じヒントあり条件で失敗

記録した試行数をモデルタグ単位で集計すると次の通りです。

Model tag記録した試行数UIログでTool実行・Provider呼び出しを確認検索結果Citationあり本文確認済みの根拠
gemma4:12b20 / 20 / 20 / 2
gemma4:12b-it-q4_K_M42 / 42 / 40 / 4
gemma4:e4b-it-q4_K_M11 / 11 / 10 / 1
gemma4:26b11 / 11 / 10 / 1

試行数は少なく、モデルの一般的な成功率を示すものではありません。今回保存した実験記録の集計です。

なお、公開前に実施した補助確認は、Promptと入力方法が本表の実験条件と異なるため、試行数には含めていません。

また、ピークメモリ、実行時間、tokens/secを共通条件で記録していないため、本記事ではモデル間の負荷を定量比較しません。

使用した調査テーマ

調査テーマは次です。

生成AIの業務利用は、初期生成時間だけでなく、人間による確認、誤りの修正、手戻りを含む総作業時間と最終成果物の品質を改善するのか。

対象領域は次の3つです。

  • ソフトウェア開発
  • 文書作成・分析業務
  • カスタマーサポート

Promptでは、複数回検索すること、一次研究を優先すること、検索結果の要約情報と本文確認を区別すること、未確認項目を推測で埋めないことを要求しました。

また、最終出力には次を含めるよう指定しました。

  • search_queries
  • searched_sources
  • evidence
  • hypothesis_patterns
  • quality_review
  • knowledge_gaps
  • follow_up_queries
  • final_assessment

このPromptは、回答をそれらしく見せるためではなく、sourceと根拠の扱いがどこで崩れるかを確認するためのものです。

E4Bでは検索結果Citation付きのResearch Draftを作れた

gemma4:e4b-it-q4_K_M の試行では、次のUIログを確認しました。

Tool Call: web-browsing({...})
@agent is executing `web-browsing` tool
@agent: Using DuckDuckGo to search for "..."
@agent: I found 10 results

最終回答には実在URLを含むsource一覧が残り、根拠、仮説、knowledge gapsも構造化されました。

この試行から、E4BでもAnythingLLMのUIログ上でTool解決、DuckDuckGo Providerの呼び出し、結果件数の返却を確認でき、検索結果Citationを保持できることが分かりました。

ただし、本記事の比較表に含めたE4Bの試行は1回です。「E4Bなら安定する」「E4BではTool名の逸脱が起きない」とは判断できません。

公開前の補助確認では、同じE4Bでも、検索結果Citationまで到達した試行と、Tool実行を確認できないまま仮想的なsourceと根拠を生成した試行の両方がありました。E4BでもTool Callingや出典取得が安定するとは判断できません。

後者では、モデルがweb_search_executed=trueと自己申告した一方、Citationは残らず、出力内で検索処理をsimulateし、検索で取得したものではなくモデルが生成した架空のURLを使ったことを明記していました。
したがって、最終回答の自己申告ではなく、Tool実行UIログとCitationの有無を確認する必要があります。

また、AnythingLLMにCitationが登録されたことと、source本文を確認したことは同じではありません。

今回取得できた情報の多くは検索結果のtitle、URL、要約情報でした。主張に対応する本文箇所や、ページ本文を取得した記録までは残っていません。

そのため、E4Bの出力はResearch Draftまたは部分的なVerifiable Draftとしては有用ですが、Research Artifactには未達です。

12BではTool Call表示の後に実行UIログが続かない試行があった

gemma4:12b の2試行では、次のような表示が出ました。

Tool Call: web_browsing({...})

一見すると、Web検索Toolを呼び出しているように見えます。

しかし、その後に次のUIログが続きませんでした。

@agent is executing `web-browsing` tool
@agent: Using DuckDuckGo to search for "..."
@agent: I found 10 results

最終回答にも検索結果Citationは残りませんでした。

それでもモデルは、指定された出力形式を埋めようとしました。その結果、source欄には次のようなプレースホルダーが入りました。

[Example Title]
[URL]

さらに、実在sourceがないにもかかわらず、サンプル数、調査期間、引用文、verified_from_body といった未確認情報まで生成されました。

当初は、12Bが検索結果の整理に失敗したのだと考えました。

しかし保存したUIログでは、Tool解決、DuckDuckGo Providerの呼び出し、結果件数の返却を確認できませんでした。したがって、検索後のsource統合より前の段階で止まった可能性があります。

AnythingLLM v1.15.0の正式なTool名は「web-browsing」

AnythingLLM v1.15.0のコードでは、Web Browsing Toolは web-browsing という名前で登録されています。

一方、失敗した試行では、underscore形式の名前が生成されていました。

web_browsing

意味としては同じWeb Browsingを指しています。しかし、function nameはプログラム上の識別子です。

AIbitatの実行処理では、モデルから返されたfunction nameを使って登録済みToolを取得しています。v1.15.0のコードでは、function callの name を受け取り、this.functions.get(name) で解決しています。

#parseFunctionName は設定されたTool名の #@@ を扱っていますが、今回確認した範囲ではhyphenとunderscoreを相互変換する処理は見つかりませんでした。

ただし、UIに表示された名前が常に内部のfunction nameと完全に同じか、OllamaやProvider Adapterを含む別の層で変換される可能性がないかまでは確認できていません。

そのため、underscore形式が唯一の原因だとは断定しません。

今回直接確認できたのは、次の対応です。

生成されたTool名is executingProvider UIログ結果件数UIログ検索結果Citation
web-browsingありありありあり
web_browsingなしなしなしなし

Citationは検索結果のtitle・URL・要約情報から作られる

AnythingLLM v1.15.0のWeb Browsing実装では、検索結果のtitle、URL、要約情報(実装上のsnippetなど)をCitationとして登録しています。

そのため、本記事でいう「検索結果Citationあり」は、次を意味します。

  • 検索結果のtitleが残った
  • 検索結果URLが残った
  • 検索結果の要約情報(実装上のsnippetまたはdescription)がCitation本文として残った

次を意味するものではありません。

  • URL先のページ本文を取得した
  • 論文PDFを読んだ
  • 主張に対応する本文箇所を保存した
  • source本文によって根拠を検証した

記事中の「出典あり」「Citation取得」は、すべてこの検索結果Citationを指します。

Promptで正式なTool名を教えれば直るのか

次に、Prompt冒頭へ次の一文を追加しました。

重要なヒント:Web検索はweb-browsingを使うこと

gemma4:12b-it-q4_K_M では、ヒントありの3試行中2試行で web-browsing が表示され、Tool解決、DuckDuckGo Providerの呼び出し、結果件数をUIログで確認できました。検索結果Citationも残りました。

しかし、同じモデル、同じヒントありPromptの別試行では、再び次が生成されました。

Tool Call: web_browsing({...})

この試行では、Tool Callらしき表示が複数回出たものの、is executing、DuckDuckGo Provider、検索結果件数のUIログは確認できず、検索結果Citationも残りませんでした。

したがって、正式なTool名をPromptへ書く方法は、安定した回避策にはなりませんでした。

ヒントが成功確率に影響した可能性はあります。しかし、3試行だけでは効果量や因果関係を評価できません。

これはTool名のハルシネーションなのか

今回の web_browsing は、意味的には正しいToolを選んでいます。

モデルはWeb検索が必要だと判断していました。問題は、AnythingLLMに登録されている識別子と一致しない名前を生成したことです。

この現象は、次のように分類できます。

  • function-name hallucination
  • Tool-name hallucination
  • Tool Call schema deviation
  • 無効なfunction identifierの生成

通常の回答で事実を捏造するハルシネーションとは性質が異なります。

モデルは何をすべきかを意味的には選べていても、実行に必要な識別子を正確に生成できない場合があります。

12B固有の問題とは断定できない

今回、Tool名の揺れを確認したのは、Gemma 4、Ollama、AnythingLLM v1.15.0を組み合わせた限られた試行です。

本記事の比較表に含めたE4Bと26Bの各1試行では同じ問題を確認していません。ただし、公開前の補助確認では、E4BでもTool実行を確認できないまま仮想sourceと根拠を生成した試行がありました。

したがって、次は断定できません。

  • E4Bでは発生しない
  • 26Bなら安全である
  • 12B固有の不具合である
  • モデルサイズだけが原因である
  • AnythingLLMだけに起こる問題である

今回の実験で他のAgent製品でも発生すると確認したわけではありません。

一方、モデルが生成したfunction nameやargumentsをRuntimeが解決・実行する構成では、無効な識別子やschema逸脱を受け取る可能性があります。これは今回の観測結果から導く設計上の推論です。

そのため、Agent Runtimeはモデル生成のTool Callを未検証の入力として扱い、解決失敗、再試行、ログ保存を設計する必要があります。

26Bは最も整理されたDraftだったが、誤りも残った

gemma4:26b の試行では、複数のWeb Browsingについて、Tool解決、DuckDuckGo Providerの呼び出し、結果件数をUIログで確認しました。実在URLを含む検索結果Citationも残りました。

12Bの失敗試行と比べると、次の点は改善しました。

  • 正式なTool名を選択した
  • 複数の検索クエリを実行した
  • 実在sourceを保持した
  • source IDと根拠を対応させた
  • 一部の不明項目を unknown とした
  • 検索結果の要約情報に対して低いconfidenceを付けた
  • 根拠と仮説を分離した

今回記録したモデルの中では、最も整理されたResearch Draftでした。

ただし、出力には次の問題が残りました。

  • MITのURLに 202ss という誤記があった
  • 根拠欄のURLが https://... に省略されていた
  • NBER Working Paperを peer_reviewed_research と分類していた
  • snippet_only のsourceから得たサンプル数などを、すべて unknown にできていなかった

したがって、Citation一覧や根拠表を、そのまま検証済みsourceリストとして利用することはできませんでした。

また、26Bでもsource本文の取得記録、主張と本文箇所の対応、Tool Response本文の完全保存はありません。

ピークメモリ、実行時間、tokens/secは共通条件で記録していないため、「26Bは負荷が高い」といった定量比較も本記事では行いません。確認できたのは、MacBook Air M5・メモリ32GBの環境で試行を実行できたことまでです。

モデル別の観測結果

曖昧な「品質:中/最良」「負荷:低/高」ではなく、保存記録から直接確認できる項目で比較します。

Model tag試行数Tool名の観測UIログ確認検索結果Citation本文確認主な出力上の問題
gemma4:12b2web_browsing0 / 20 / 20 / 2プレースホルダーsource、未確認情報の生成
gemma4:12b-it-q4_K_M4web-browsingweb_browsing2 / 42 / 40 / 4Tool名と実行成否が同一条件でも揺れた
gemma4:e4b-it-q4_K_M1web-browsing1 / 11 / 10 / 1長期的な再現性は未評価、根拠は主に検索結果の要約情報
gemma4:26b1web-browsing1 / 11 / 10 / 1URL誤記・省略、source type誤分類、unknown規則の不徹底

この結果は、パラメータ数に比例して単純に改善したことを示しません。

また、試行数が少ないため、モデル間の一般的な優劣や成功率を示すベンチマークでもありません。

Tool Call表示だけでは成功と判断できない

今回の最も重要な発見は次です。

Tool Call: と表示されても、AnythingLLMのUIログ上でTool解決やProvider呼び出しを確認できるとは限らない。

今回の保存記録から確認できる段階を分けると、次のようになります。

段階確認する内容
Tool intentモデルがWeb検索を必要と判断したか
Tool Call displayUIにどのTool名が表示されたか
Tool resolutionis executing が表示されたか
Provider callUsing DuckDuckGo が表示されたか
Result return検索結果件数が表示されたか
Search-result Citationtitle、URL、検索結果の要約情報を使ったCitationが最終回答に残ったか
Body verificationURL先本文と主張の対応を確認したか

次の表示だけでは不十分です。

Tool Call: web_browsing({...})

次の一連のログが残れば、少なくともAnythingLLMのUIログ上では、Tool解決、Provider呼び出し、結果件数の返却まで確認できます。

Tool Call: web-browsing({...})
@agent is executing `web-browsing` tool
@agent: Using DuckDuckGo to search for "..."
@agent: I found 10 results

ただし、これもサーバーログやHTTPトレースの代わりではありません。

AnythingLLMはResearch Workflowとして使えるか

今回の範囲では、AnythingLLMを次のように評価できます。

できたこと

  • ローカルLLMからWeb BrowsingのTool Callを生成する
  • 成功試行ではTool解決とProvider呼び出しをUIログで確認する
  • 複数の検索クエリを生成する
  • 検索結果URLと検索結果の要約情報をCitationとして残す
  • 根拠と仮説を構造化する
  • knowledge gapsと追加検索を整理する
  • Research Draftまたは部分的なVerifiable Draftを作る

不安定だったこと

  • 登録済みTool名の正確な生成
  • 同じ条件でのTool実行再現性
  • 検索結果Citationの保持
  • source情報の正確な転記
  • source typeの分類
  • 未確認項目を unknown にする規則の遵守
  • 自己レビューによる違反検出

できなかったこと

  • 外部リクエストをサーバーログやHTTPトレースで直接確認する
  • 本文確認済みの根拠を安定して保存する
  • 主張と本文箇所を対応させる
  • Tool CallとTool Responseを完全保存する
  • 検索から結論までの再実行可能な記録を残す
  • Human ReviewなしでResearch Artifactを完成させる

AnythingLLMは、Research Draftを作るWorkspaceとしては有用です。

一方、出力をそのまま検証済み調査結果として扱うには不足があります。

実運用ではどう使うべきか

現時点では、次の運用が現実的です。

  1. AnythingLLMでResearch Draftを生成する
  2. Tool Call表示だけで検索済みと判断しない
  3. is executing、検索Provider、検索結果件数のUIログを確認する
  4. 検索結果Citationが残っているか確認する
  5. Citationを本文確認済みの根拠と解釈しない
  6. source本文を人間が開く
  7. 検索結果の要約情報と本文確認済みの根拠を分ける
  8. URL、source type、数値、主張とsourceの対応をレビューする
  9. Tool実行をUIログで確認できない回答は破棄または再実行する

本来、この種の問題はモデル選択やPromptだけに頼るのではなく、Agent Runtime側で吸収すべきです。

例えば、次の対策が考えられます。

  • 未登録Tool名を受け取ったら明示的にエラーにする
  • requested tool nameとresolved tool nameを別々に記録する
  • 一意に判断できる表記揺れだけを正規化する
  • Tool名解決に失敗したら登録済みTool一覧を再提示して再試行する
  • Tool Responseがない回答を検索済みとして扱わない
  • Tool Call、Tool Response、検索クエリ、結果URL、Citationを保存する

これは、Local Research Agent Workspaceで重視している「検索できることではなく、検証可能なResearch Artifactを作れること」に直結します。

まとめ:Tool Callできることと、検証できることは別

今回の検証では、AnythingLLMとローカルLLMを使って、複数のsource、根拠、仮説、knowledge gapsを含むResearch Draftを生成できました。

成功した試行では、AnythingLLMのUIログ上で、Tool解決、DuckDuckGo Providerの呼び出し、検索結果件数の返却を確認できました。検索結果のtitle、URL、検索結果の要約情報を使ったCitationも残りました。

一方、Tool Calling対応モデルでも、登録済みTool名と異なる名前を生成する試行がありました。

gemma4:12b-it-q4_K_M では、同じヒントありPromptでも、正式な web-browsingweb_browsing が揺れました。

前者の試行では実行関連のUIログと検索結果Citationが残り、後者の試行ではTool Call表示だけで、その後のUIログとCitationを確認できませんでした。Promptで正式名を明示しても、この揺れは完全には防げませんでした。

本記事の比較表に含めたE4Bと26Bの各1試行では実行関連のUIログと検索結果Citationが残りましたが、同種の問題が起きないことを証明したわけではありません。

さらに、公開前の補助確認では、E4BでもCitationが残らず、Tool実行を確認できないまま仮想sourceと根拠を生成する試行がありました。モデルを変えてもTool Callingと出典取得の再現性は保証されません。

また、26Bは最も整理されたDraftを出しましたが、URLの誤記・省略、source typeの誤分類、unknown 規則の不徹底が残りました。

さらに、どのモデルでも本文確認済みの根拠、主張と本文箇所の対応、Tool Responseの完全保存までは実現できませんでした。

したがって、現時点の結論は次です。

AnythingLLMは、ローカルLLMで検索結果Citation付きのResearch Draftや部分的なVerifiable Draftを作る用途には使える。しかし、Tool Callの再現性、本文確認、根拠の追跡可能性には不足があり、そのまま検証可能なResearch Artifactとして扱うことはできない。

重要なのは、Tool Callと表示されたことではありません。

どのTool名が生成され、AnythingLLMのUIログ上でどこまで実行を確認でき、どの検索結果Citationを根拠候補として使い、本文確認によって何を検証したかを後から追跡できることです。

Xでフォローしよう

おすすめの記事