Skip to main content

統一されたツール抽象化

FIM Oneの中心的な設計洞察は、エージェントが実行できるすべてのものはツールということです。計算機、ナレッジベースクエリ、ERP API呼び出し、サードパーティMCPサーバーはすべて同じToolプロトコルを実装しています:namedescriptionparameters_schemacategoryrun()。エージェントは、ローカルPython関数を呼び出しているのか、ベクトルデータベースをクエリしているのか、レガシーシステムにプロキシしているのか、コミュニティMCPサーバーを呼び出しているのかを知りません。ToolRegistry内の呼び出し可能なツールのフラットなリストを見ます。 これは意図的なアーキテクチャ上の選択であり、偶然の単純化ではありません。つまり、新しい機能ソースを追加する際に、エージェント、実行エンジン、またはコンテキスト管理レイヤーを変更する必要がないということです。ツールを登録すれば、エージェントがそれらを使用します。 6つの機能ソースが1つのレジストリに収束します。エージェントはそれらすべてから等しく引き出します。最後の2つはペアになっています:Skill動的レシピ(LLMが段階的に解釈するSOP)であり、Workflow静的レシピ(毎回同じ方法で実行される決定論的グラフ)です。どちらもread_skillrun_workflowというツールを通じて取得され、どちらも他方を含みません。それらはピアであり、同じランタイムによって消費されます。

6つの機能ソース

組み込みツール

discover_builtin_tools() によるスタートアップ時の自動検出。core/tool/builtin/BaseTool サブクラスをドロップすると、設定なしで登録されます。カテゴリには計算(calculatorpython_exec)、ウェブ(web_searchweb_fetch)、ファイルシステム(file_ops)、および一般的なもの(email_sendjson_transformtemplate_rendertext_utils)が含まれます。これらはエージェントのネイティブ機能です。常に利用可能で、セットアップは不要です。

ナレッジベース

条件付き。エージェントが kb_ids をバインドしている場合、汎用の kb_retrieve ツールは特殊な検索ツールに置き換わります。シンプルモードでは、KBRetrieveTool は基本的な RAG 検索を実行します。グラウンディングモードでは、GroundedRetrieveTool は 5 段階のパイプラインを実行します:マルチ KB 検索、引用抽出、アライメントスコアリング、競合検出、および信頼度計算。ナレッジベースはエージェントの横に位置する独立したサブシステムではなく、エージェント内に特殊なツールとして組み込まれ、他のすべてのツールと同じ Tool プロトコルの対象となります。

コネクタ

ConnectorToolAdapter はエンタープライズシステムのアクションをツールとしてラップします。各アクションは {connector}__{action} という名前のツールになり、connector カテゴリに分類されます。アダプタは、認証注入(ベアラー、APIキー、基本認証)を備えたHTTPプロキシ、操作レベルのアクセス制御(読み取り/書き込み/管理者)、レスポンス切り詰め、および監査ログを追加します。直接的なデータベースアクセスの場合、DatabaseToolAdapter はスキーマ対応のSQL実行とオプションの読み取り専用強制を提供します。コネクタはAIとレガシーシステム間のブリッジであり、コア差別化要因です。詳細な設計については コネクタアーキテクチャ を参照してください。

MCP

外部MCPサーバーは標準プロトコルを介してサードパーティツールを提供します。各サーバーは独自のプロセス(stdioまたはHTTPトランスポート)で実行され、プラットフォームから完全に隔離されています。ツールはToolプロトコルに適応され、mcpカテゴリの下に登録されます。管理者は、すべてのユーザーに対して自動的にロードされるグローバルMCPサーバーをプロビジョニングできます。MCPはエコシステムの取り組みです。MCPと互換性のあるサーバーはカスタム統合なしで動作します。

スキル

スキルは再利用可能な標準作業手順(SOP)です。企業ポリシー、対応手順、段階的なワークフローなど、選択されたエージェントに関係なくグローバルに適用されます。コネクタとナレッジベース(特定のエージェントにスコープできます)とは異なり、スキルは可視性(個人、組織共有、またはマーケット購読)に基づいて、すべてのユーザーに対して常にロードされます。 スキルは2つのインジェクションモード(段階的(デフォルト)とインライン)をサポートしており、SKILL_TOOL_MODEで制御されます。段階的モードでは、コンパクトなスタブがシステムプロンプトに表示され、LLMは必要に応じてread_skill(name)を呼び出します。これは、スキル、コネクタ、データベース、MCP サーバー全体に同じスタブファースト、オンデマンド詳細パターンを適用する、より広い段階的情報開示アーキテクチャの一部です。 スキルがグローバル(エージェント非依存)である理由と、デュアルモードリソース検出との相互作用について詳しく知るには、エージェント&リソース検出を参照してください。

ワークフロー

ワークフローはスキルの静的レシピです。決定論的なDAGであり、サブタスクが毎回同じように実行され、監査証跡を残す必要がある場合にエージェントが利用します(スケジュール済み調整、複数ステップの承認不要パイプライン)。スキルと同様に、実行可能なワークフローはユーザーごとに可視性に基づいてグローバルに読み込まれ、エージェント選択とは独立して、単一の run_workflow(name, inputs) ツールを通じて公開されます。各ワークフローの入力フィールドはコンパクトなシステムプロンプトスタブとして通知されます。LLMはタスクがそれにマップされるとき、名前でワークフローを取得します。 アクティブで、人間による承認(HUMAN_INTERVENTION)ノードがないワークフローのみがインライン実行可能です。ゲートが数分から数時間ブロックする場合、エージェントターン内に配置することはできないため、これらのワークフローはワークフローページからのトリガーのみとなります。インライン実行はワークフロー所有者として実行され(サブスクライブされたワークフローはパブリッシャーのバインドされた認証情報を使用)、監査証跡のための WorkflowRun を永続化し、再入性ガードとネストの深さ上限によって保護されるため、ワークフローの AGENT ノードが無制限の呼び出しサイクルを開始することはできません。

リクエストごとのツールアセンブリ

すべてのチャットリクエストは、_resolve_tools()のフィルタリングパイプラインを通じて、リクエストごとに新しいツールセットをアセンブリします。これは静的な設定ではなく、エージェントの設定、ユーザーのアイデンティティ、利用可能なコネクタとMCPサーバーに基づいて計算されます。 8つのステップ:
  1. ベース検出。 discover_builtin_tools()はすべての組み込みツールを読み込み、会話のサンドボックスにスコープします。
  2. エージェントカテゴリフィルタ。 filter_by_category(*agent.tool_categories)は、エージェントが使用を許可されているカテゴリのみに制限します。
  3. KB注入。 エージェントがkb_idsを持つ場合、汎用検索ツールは検索モードに基づいてKBRetrieveToolまたはGroundedRetrieveToolに置き換えられます。
  4. コネクタ読み込み。 エージェント制約モードでは、エージェントにバインドされたコネクタのみが読み込まれます。オートディスカバリーモード(エージェント未選択)では、ユーザーに表示されるすべてのコネクタが読み込まれます。APIコネクタ(ConnectorMetaTool)とデータベースコネクタ(DatabaseMetaTool)の両方は、デフォルトでプログレッシブディスクロージャを使用します——システムプロンプトの軽量スタブ、必要に応じて読み込まれる完全なスキーマ。
  5. MCP読み込み。 ユーザーの個人MCPサーバーと管理者がプロビジョニングしたグローバルMCPサーバーが読み込まれて接続されます。プログレッシブモード(デフォルト)では、単一のMCPServerMetaToolがすべてのサーバーを統合します。LLMは必要に応じてdiscoverおよびcallサブコマンドを呼び出します。プログレッシブディスクロージャを参照してください。
  6. スキル+ワークフロー注入。 ユーザーに表示されるすべてのアクティブなスキルが読み込まれます——エージェント選択に関係なく。プログレッシブモードでは、ReadSkillToolはシステムプロンプトのコンパクトスタブで登録されます。インラインモードでは、完全なスキルコンテンツが直接埋め込まれます。同じステップがすべてのアクティブでインラインで実行可能なワークフローを読み込み、RunWorkflowToolを1つのワークフローあたり1つのスタブ(名前、説明、入力フィールド)で登録します。人間の承認ノードを含むワークフローはここではスキップされます。
  7. CallAgentの登録(オートモードのみ)。 特定のエージェントが選択されていない場合、すべてのアクティブで表示されるエージェントがカタログにアセンブリされ、CallAgentToolを通じて公開されます。これにより、LLMはタスクをスペシャリストエージェントに委譲できます。委譲されたエージェントは、独自の設定から構築された完全なToolRegistryを受け取りますが、無限再帰を防ぐためにcall_agentを除外します。特定のエージェントが選択されている場合、CallAgentToolは登録されません——エージェントは専門化されており、他のエージェントに委譲しません。これにより、マーケットプレイスエージェントが他のエージェントのプライベートプロンプトにアクセスするのを防ぎます。
  8. ランタイム選択。 ツールの総数が12を超える場合、軽量なLLM呼び出しがこの特定のクエリに最も関連するサブセット(最大6個)を選択します。request_toolsメタツールが自動的に登録され、LLMが会話の途中で追加のツールを動的に読み込むことができます。初期選択で必要なツールが見落とされた場合です。選択失敗は致命的ではありません——エージェントは完全なセットにフォールバックします。プログレッシブディスクロージャを参照してください。
  9. フック登録。 エージェントの宣言されたフック(model_config_json.hooksから)がインスタンス化され、HookRegistryに接続されます。選択されたツール呼び出しはそれぞれラップされます:PreToolUseフックは実行前に引数をブロックまたは書き直すことができます。PostToolUseフックは、観測がLLMに返される前に書き直すことができます。フックはLLMループの外で実行され、エージェント命令によってバイパスされることはできません——フックシステムを参照してください。
結果:エージェントは必要なツールのみを見ます。コネクタがなくKBもない単純なエージェントは5つのツールを見るかもしれません。3つのエンタープライズシステムに接続され、グラウンデッド知識ベースと2つのMCPサーバーを持つハブエージェントは30個を見るかもしれません——しかし選択後、最も関連性の高い6個だけがコンテキストに入ります。

When to use what

カテゴリは相互に排他的ではありません。単一の智能体は1つの会話内で5つの機能ソースすべてを使用できます——苦情処理SOP用のSkillを読み込み、ポリシードキュメント用にナレッジベースをクエリし、ERP確認用にコネクタを呼び出し、分析を専門の智能体に委譲し(Autoモード)、結果をフォーマットするために組み込みツールを使用します。

実行エンジンは直交している

ツールシステムと実行エンジンは独立した関心事です。LLM駆動エンジン(ReActとDAG)は同じ ToolRegistry からツールを消費します。エンジンの選択は、ツールがどのように調整されるかに影響しますが、どのツールが利用可能かには影響しません。 ReAct は反復的なツールループです。エージェントは推論し、ツールを選択し、結果を観察し、完了するまで繰り返します。前のステップの結果に次のステップが依存する、探索的で会話的なタスクに優れています。ループは最大50回の反復を実行し、ContextGuardを介した反復ごとのコンテキスト管理を行います。実装の詳細については、ReAct Engine を参照してください。 DAG は目標を2~6個の並列ステップに分解します。各ステップは独立したReActエージェントを実行します。PlanAnalyzerは目標が達成されたかどうかを評価し、達成されていない場合、パイプラインは自律的に再計画します(最大3ラウンド)。DAGは、「3つのソースを検索して結果を比較する」のように、明確なサブタスクを持ち、並行実行できるタスクに優れています。これは3回の検索の時間ではなく、1回の検索の時間で完了します。完全なパイプラインについては、DAG Engine を参照してください。 2つのエンジンは、信頼性の高い構造化出力のための structured_llm_call、トークン予算の強制のための ContextGuard、ツール解決のための ToolRegistry などのインフラストラクチャを共有しています。新しいツールを追加するには、どちらのエンジンも変更は不要です。新しいエンジンを追加する場合(必要になった場合)、ツールシステムへの変更は不要です。 両方のエンジンは、オートモード(エージェント未選択)の場合、CallAgentTool を介したエージェント委譲もサポートしています。ネイティブ関数呼び出しモードでは、LLMは単一のターンで複数の call_agent 呼び出しを実行でき、これらは asyncio.gather を介して並行実行されます。各委譲されたエージェントは独自の ToolRegistry を受け取り、完全な実行ユニットとして実行されます。エージェント発見、グローバルSOPとしてのスキル、およびエージェント委譲の詳細な設計については、Agent & Resource Discovery を参照してください。

ワークフローエンジン — 第3のパラダイム

LLM駆動のReActおよびDAGエンジンと並んで、FIM Oneはワークフローエンジンを備えています。これは9つのコアノードタイプ(Start、End、LLM、Condition Branch、Agent、Knowledge Retrieval、Connector、MCP、Human Intervention)を持つビジュアルDAGエディタで、固定プロセスの自動化に使用します。柔軟で探索的なタスクにはAgentを使用し、決定論的で反復可能なプロセスにはWorkflowを使用します。詳細はExecution Modesを参照してください。 この2つは双方向で構成されますが、各方向は単一のランタイム(エージェントループ)を通じてルーティングされ、第2の実行エンジンを通じてはルーティングされません。
  • Workflow → Agent。 WorkflowのAGENTノードは、1つの決定論的なステップとしてエージェントを実行します。
  • Agent → Workflow。 エージェント(またはそれが従っているSkill)はrun_workflowを呼び出して、決定論的に実行する必要があるサブタスクを委譲します。
これは明らかなサイクルの懸念を解決するものです。エージェントループだけがランタイムです。SkillsとWorkflowsは、それが読み込む不活性なレシピであり、相互に実行されることはありません。「SkillがWorkflowを呼び出す」は物理的には、エージェントがSkillのSOPに従いながらrun_workflowを呼び出すことを意味します。すべての呼び出しはエージェントを通じて渡されるため、呼び出しグラフはスターであり、メッシュではありません。また、バックエッジは制限されています(read_skillはテキストのみを返し、call_agentrun_workflowは深さキャップと再入性ガードを持ちます)。 同じ図の2つの読み方:ツールはプッシュされるのではなくプルされます(LLMが選択しないSkillまたはWorkflowは単に発火しません。これが動的機能がクエリが1つにマッチするまで見えない可能性がある理由です)。また、SkillsとWorkflowsはピアであり、相互にネストされるのではなく1つのランタイムを通じてルーティングされます。

ライフサイクル概要

スタートアップ。 start.sh は Alembic マイグレーションを実行し、FastAPI サーバーを起動し、組み込みツールを検出し、事前設定されたグローバルサーバーの MCP サーバー接続を確立します。 リクエストごと。 JWT 認証、エージェント設定ルックアップ、ツール組み立て(上記の8ステップパイプライン)、エンジン選択(エージェント設定に基づく ReAct または DAG)、SSE ストリーミングによる実行、および結果の永続化。 横断的な関心事。 コンテキスト管理(5層 token 予算)は、すべての LLM 呼び出しをオーバーフローから保護します。フックシステムは、すべてのツール呼び出しをプラットフォーム制御の PreToolUse / PostToolUse ロジックでラップします — ヒューマンインザループ承認(FeishuGateHook)、監査ログ、読み取り専用モード強制の仕組みです。監査ログはすべてのコネクタツール呼び出しを追跡します。サンドボックス分離はコード実行ツールを含みます。2つの LLM アーキテクチャ(スマート + 高速)は、計画、実行、合成全体のコストを最適化します。 このアーキテクチャは、各関心事 — ツール登録、実行オーケストレーション、コンテキスト管理、セキュリティ — が独立して進化できるように設計されています。新しいコネクタタイプ、新しい実行エンジン、または新しいコンテキスト戦略は、システム全体に連鎖的な変更を引き起こすことなく追加できます。