AgentScope

最終更新: 2023-05-05 11:54:52 +0800 +0800
tags: Ai | Agents | Java | Spring-Boot | Llm
原文は英語で書かれています。あなたはAI翻訳版を読んでいます。

AgentScope は、大規模言語モデルが推論し、ツールを呼び出し、状態を保持し、ユーザーや他のエージェントと協調できるアプリケーションを構築・運用するためのオープンソースフレームワークです。Alibaba によって開始され、Python 向けと Java 向けの個別プロジェクトとして提供されています。

通常のモデル呼び出しは、アプリケーションが制御する短い経路を持ちます。

text
application -> prompt -> model -> response

エージェントは実行ループを追加します。

text
user goal
   |
   v
model reasons -> chooses a tool -> application executes it
      ^                                  |
      +----------- tool result <---------+
   |
   v
final answer, interruption, or next action

モデル自体が Java や Python の関数を実行するわけではありません。モデルは構造化されたリクエストを出力し、AgentScope はツールシステムを通じてそのリクエストを検証・ディスパッチします。フレームワークは、このループを取り巻くメッセージ、イベントストリーム、権限、セッション状態、繰り返しのモデル呼び出しも管理します。

この記事では AgentScope 2.0 を説明し、AgentScope Java 2.0.0 に焦点を当てます。AgentScope は急速に進化しているため、以前の 1.x API 向けの例は変更なしでは動作しない場合があります。

Python と Java は別々の実装 #

AgentScope という名前は、すべての言語で変更なしに実行できる 1 つのライブラリではなく、エコシステムを指します。

Python プロジェクト には Python 3.11 以降が必要です。非同期エージェントフレームワーク、イベントシステム、ツールとリソースの権限、ミドルウェア、ワークスペース、サンドボックス統合、マルチセッションサービス、マルチエージェントチームを提供します。

AgentScope Java は JDK 17 以降を必要とするネイティブ JVM 実装です。ノンブロッキング実行 API に Project Reactor を使用し、Java ネイティブのモデル、ツール、メッセージ、イベント、状態ストア、ミドルウェア、権限、ワークスペース、サンドボックス、分散デプロイ用コンポーネントを提供します。

2 つの実装は設計思想を共有しますが、インプロセスのオブジェクトやソース互換 API は共有しません。Java アプリケーションには、次の 2 つの妥当な統合方法があります。

  1. AgentScope Java を JVM に直接組み込む。
  2. Python AgentScope アプリケーションをサービスとして実行し、バージョン管理されたネットワーク API または A2A などのエージェントプロトコル経由で呼び出す。

リクエストごとに Python インタープリターを起動したり、実行中の Python エージェントを Java にシリアライズしようとしたりしないでください。プロセス境界には、明示的なサービス契約、認証、タイムアウト動作、セッション所有権が必要です。

コア概念 #

メッセージとコンテンツ #

メッセージはエージェントを介して入力と出力を運びます。AgentScope Java は UserMessage でユーザー入力を表し、テキスト、画像、ファイル、音声、動画、ツール呼び出し、ツール結果向けの型付きコンテンツブロックをサポートします。

ロールの検証は重要です。モデルのレスポンス、ユーザー指示、ツール結果は信頼レベルが異なるため、1 つの非構造化プロンプトに平坦化すべきではありません。

モデル #

モデル層は、プロバイダー固有の拡張を備えた共通のチャットモデル契約を提供します。AgentScope Java 2.0 には、次のようなプロバイダー向けモジュールが含まれます。

  • Alibaba DashScope と Qwen
  • OpenAI および OpenAI 互換エンドポイント
  • Anthropic Claude
  • Google Gemini
  • Ollama
  • サポートされている拡張経由で公開されるその他のプロバイダー

抽象化により Java API の境界でモデルを置き換えられますが、モデルの動作は同一ではありません。ツール呼び出しの品質、構造化出力、マルチモーダル対応、コンテキスト制限、推論制御、ストリーミングのセマンティクスは、選択したモデルに依存します。

ツールとツールキット #

ツールは、モデルがリクエストできる機能です。AgentScope はツール定義から JSON スキーマを生成し、そのスキーマをモデルに送信し、モデルのツールリクエストを解析して Java 実装を呼び出します。

Toolkit はエージェントが利用できるツールをまとめます。ツールキットの制限は最も重要なセキュリティ制御の 1 つです。エージェントからツールが見えなければ、フレームワークにそのツールを呼び出させることもできません。

ツールの説明は、モデルに対する運用上の指示です。操作の内容、引数の意味、外部作用や不可逆な作用の有無を記述してください。曖昧な説明は誤った呼び出しにつながります。

ReAct ループ #

ReActAgent は AgentScope Java の基本的な推論・行動エージェントです。1 回の実行中に、次の処理を繰り返します。

  1. システムプロンプト、メッセージ、利用可能なツールからモデルコンテキストを構築する。
  2. モデルを呼び出す。
  3. 型付きイベントを出力する。
  4. 許可された場合、要求されたツールを実行する。
  5. ツール結果をコンテキストに追加する。
  6. 最終結果を生成するか停止条件に到達するまで続行する。

アプリケーションが周辺インフラの大部分を自ら制御し、集中的な会話ループまたはツール呼び出しループを必要とする場合は ReActAgent を使用します。

HarnessAgent #

HarnessAgent は同じ推論コアを基盤として、長時間にわたるオープンエンドな作業に対応します。ハーネスには次の機能を追加できます。

  • ワークスペースとファイルシステム抽象化
  • コンテキスト圧縮
  • 階層化メモリ
  • 再利用可能なスキル
  • 計画
  • サブエージェント
  • サンドボックス実行
  • 永続状態とリカバリ

3 つの業務サービスを呼び出すカスタマーサポートアシスタントには ReActAgent だけで十分な場合があります。一方、リポジトリを 1 時間探索し、ファイルを編集し、レビューを委譲し、再起動後も処理を継続するコーディングエージェントには HarnessAgent が適しています。自律性が高まるほどリスクも増えるため、機能が多いという理由だけで大きなハーネスをデフォルトにすべきではありません。

イベント #

エージェントの実行は型付きイベントストリームを生成します。イベントには、テキスト差分、モデル呼び出し、ツール呼び出し、結果、確認要求、エラー、最終結果が含まれます。そのため、Web UI はログテキストを解析せずに進捗を表示できます。

イベントストリームは、可観測性と監査ロジックを接続する場所としても適しています。本番アプリケーションでは通常、ツール名、所要時間、結果、モデル使用量、セッション、認証済み主体を記録し、秘密情報を含む可能性があるメッセージとツールの内容はマスキングします。

ランタイムコンテキストと状態 #

RuntimeContext は 1 回の呼び出しを識別します。userId、sessionId、型付きのアプリケーションオブジェクトを保持できます。Java ツールは、そのようなオブジェクトをモデルに送信する JSON スキーマに公開せず受け取れます。

この区別により、重大な認可ミスを防止できます。モデルは orderId を指定できますが、その注文の認可に使う信頼済みの tenantId やユーザー ID を指定してはいけません。アプリケーションは Spring Security から ID を取得し、RuntimeContext 経由で注入します。

会話履歴やその他の復元可能な状態は AgentStateStore に保存します。ローカル JSON ストレージは開発に有用です。複数レプリカ構成では、別のレプリカが同じセッションを再開できるよう、サポートされている Redis 実装やリレーショナルデータベース実装などの共有ストレージが必要です。

最小限の Python エージェント #

次のコマンドで Python フレームワークをインストールします。

bash
pip install agentscope

AgentScope Python 2.0 は非同期 API を使用します。最小限のエージェントは次のようになります。

python
import asyncio
import os

from agentscope.agent import Agent
from agentscope.credential import DashScopeCredential
from agentscope.message import UserMsg
from agentscope.model import DashScopeChatModel


async def main() -> None:
    agent = Agent(
        name="assistant",
        system_prompt="You are a concise technical assistant.",
        model=DashScopeChatModel(
            credential=DashScopeCredential(
                api_key=os.environ["DASHSCOPE_API_KEY"],
            ),
            model="qwen3.6-plus",
        ),
    )

    async for event in agent.reply_stream(
        UserMsg("alice", "Explain optimistic locking."),
    ):
        print(event)


asyncio.run(main())

実際のアプリケーションでは通常、型によってイベントを選択し、意図的に制限したツールキットを登録し、セッション状態を永続化し、ユーザーにエージェントを公開する前に権限を設定します。

AgentScope Java を始める #

依存関係を追加する #

AgentScope Java 2.0 には JDK 17 以降が必要です。基本的な ReActAgent には、コアモジュールと 1 つのモデルプロバイダー拡張が必要です。

xml
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.agentscope</groupId>
      <artifactId>agentscope-bom</artifactId>
      <version>2.0.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>io.agentscope</groupId>
    <artifactId>agentscope-core</artifactId>
  </dependency>
  <dependency>
    <groupId>io.agentscope</groupId>
    <artifactId>agentscope-extensions-model-dashscope</artifactId>
  </dependency>
</dependencies>

HarnessAgent とそのワークスペース指向の機能が必要な場合は、コア依存関係の代わりに、またはコア依存関係に加えて agentscope-harness を使用します。その他のモデル拡張には、agentscope-extensions-model-openai、agentscope-extensions-model-anthropic、agentscope-extensions-model-gemini、agentscope-extensions-model-ollama などがあります。

エージェントを作成する #

次のプログラムは DashScope を使用します。API キーはソースコードではなく環境変数から読み取ります。

java
import io.agentscope.core.ReActAgent;
import io.agentscope.core.message.Msg;
import io.agentscope.core.message.UserMessage;
import io.agentscope.extensions.model.dashscope.DashScopeChatModel;

public class FirstAgent {

    public static void main(String[] args) {
        var model = DashScopeChatModel.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .modelName("qwen-plus")
                .stream(true)
                .build();

        var agent = ReActAgent.builder()
                .name("technical-assistant")
                .sysPrompt("""
                        You are a technical assistant.
                        Distinguish facts from assumptions.
                        Ask before performing a destructive operation.
                        """)
                .model(model)
                .build();

        Msg result = agent.call(
                new UserMessage("Explain write skew in two paragraphs.")
        ).block();

        System.out.println(result.getTextContent());
    }
}

AgentScope は Reactor 型を公開します。コマンドラインプログラムの外側の境界で block() を呼び出すことは許容されます。リアクティブサーバーでは、リクエストスレッドをブロックせずに Mono または Flux を返してください。

Java ツールを追加する #

アプリケーションに既存の OrderService があるとします。エージェントアダプターは、ビジネスロジックを複製したり、アプリケーション自身の REST エンドポイントを呼び出したりせず、そのサービスに委譲すべきです。

java
import io.agentscope.core.tool.Tool;
import io.agentscope.core.tool.ToolParam;

public final class OrderTools {

    private final OrderService orders;

    public OrderTools(OrderService orders) {
        this.orders = orders;
    }

    @Tool(
            name = "get_order",
            description = "Get the current state of an order visible to the caller",
            readOnly = true)
    public OrderView getOrder(
            @ToolParam(
                    name = "order_id",
                    description = "Numeric order ID")
            long orderId,
            RequestIdentity identity) {
        return orders.get(identity.tenantId(), identity.userId(), orderId);
    }

    @Tool(
            name = "cancel_order",
            description = """
                    Cancel an order that has not shipped. This changes business
                    state and must be approved by the user before execution.
                    """)
    public OrderView cancelOrder(
            @ToolParam(
                    name = "order_id",
                    description = "Numeric order ID")
            long orderId,
            @ToolParam(
                    name = "reason",
                    description = "Business reason for cancellation")
            String reason,
            RequestIdentity identity) {
        return orders.cancel(
                identity.tenantId(),
                identity.userId(),
                orderId,
                reason);
    }
}

orderId と reason には @ToolParam が付いているため、モデルはこれらをツールスキーマ内で認識します。RequestIdentity にはアノテーションが付いていません。AgentScope は呼び出しごとの RuntimeContext からこれを注入するため、モデルはこの引数を偽造して別のテナントになりすますことができません。

ツールオブジェクトをツールキットに登録します。

java
Toolkit toolkit = new Toolkit();
toolkit.registerTool(new OrderTools(orderService));

ReActAgent agent = ReActAgent.builder()
        .name("order-assistant")
        .sysPrompt("""
                Help users inspect their orders.
                Never cancel an order without explicit approval.
                """)
        .model(model)
        .toolkit(toolkit)
        .build();

Java アノテーションにより、単純な同期ツールを便利に作成できます。権限チェック、非同期実行、構造化メタデータをより細かく制御するために、AgentScope Java は低レベルのツール抽象化も提供します。

AgentScope Java と Spring Boot の統合 #

AgentScope Java はフレームワークに依存しないため、Spring Boot アプリケーションには通常の Java オブジェクトとして統合します。推奨される境界は次のとおりです。

text
REST or WebSocket controller
        |
        v
AgentScope agent factory
        |
        +----> model provider
        +----> application tools ----> existing Spring services
        +----> shared state store

次の例では、SSE チャットエンドポイントを公開します。各呼び出しで新しい ReActAgent を意図的に作成します。ReActAgent インスタンスは並行呼び出しに対して安全ではありませんが、モデルと状態ストアは共有できます。ツールキットはエージェント構築時にコピーされます。

共有コンポーネントを構成する #

java
import io.agentscope.core.ReActAgent;
import io.agentscope.core.state.AgentStateStore;
import io.agentscope.core.state.JsonFileAgentStateStore;
import io.agentscope.core.tool.Toolkit;
import io.agentscope.extensions.model.dashscope.DashScopeChatModel;
import java.nio.file.Path;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@ConfigurationProperties(prefix = "app.agent")
record AgentProperties(String apiKey, String model) {
}

@Configuration
@EnableConfigurationProperties(AgentProperties.class)
class AgentConfiguration {

    @Bean
    DashScopeChatModel agentModel(AgentProperties properties) {
        return DashScopeChatModel.builder()
                .apiKey(properties.apiKey())
                .modelName(properties.model())
                .stream(true)
                .build();
    }

    @Bean
    AgentStateStore agentStateStore() {
        return new JsonFileAgentStateStore(
                Path.of(".agentscope", "sessions"));
    }

    @Bean
    Toolkit orderToolkit(OrderService orders) {
        Toolkit toolkit = new Toolkit();
        toolkit.registerTool(new OrderTools(orders));
        return toolkit;
    }

    @Bean
    OrderAgentFactory orderAgentFactory(
            DashScopeChatModel model,
            AgentStateStore stateStore,
            Toolkit orderToolkit) {
        return new OrderAgentFactory(model, stateStore, orderToolkit);
    }
}

非秘密の値は通常どおり構成し、API キーはシークレットマネージャーまたは環境変数から提供します。

yaml
app:
  agent:
    model: qwen-plus
    api-key: ${DASHSCOPE_API_KEY}

モデルの認証情報をブラウザーに公開しないでください。

ファクトリは安全なインフラストラクチャを再利用しながら、分離されたエージェント実行を作成します。

java
public record OrderAgentFactory(
        DashScopeChatModel model,
        AgentStateStore stateStore,
        Toolkit toolkit) {

    ReActAgent create() {
        return ReActAgent.builder()
                .name("order-assistant")
                .sysPrompt("""
                        Help the authenticated user inspect orders.
                        Use tools for current order data.
                        Never claim that a mutation succeeded unless its tool
                        returned a successful result.
                        """)
                .model(model)
                .stateStore(stateStore)
                .toolkit(toolkit)
                .build();
    }
}

ローカル開発では JsonFileAgentStateStore で十分です。複数のアプリケーションレプリカを実行する前に、サポートされている共有状態ストアに置き換えてください。コンテナ内のローカルディレクトリは、耐久性のあるセッションストレージではありません。

SSE エンドポイントを公開する #

java
import io.agentscope.core.agent.RuntimeContext;
import io.agentscope.core.event.TextBlockDeltaEvent;
import io.agentscope.core.message.UserMessage;
import java.security.Principal;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

record ChatRequest(String sessionId, String message) {
}

record RequestIdentity(String tenantId, String userId) {
}

@RestController
@RequestMapping("/api/assistant")
class AgentController {

    private final OrderAgentFactory agents;
    private final TenantResolver tenants;

    AgentController(OrderAgentFactory agents, TenantResolver tenants) {
        this.agents = agents;
        this.tenants = tenants;
    }

    @PostMapping(
            path = "/messages",
            produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    Flux<String> chat(
            @RequestBody ChatRequest request,
            Principal principal) {
        String userId = principal.getName();
        String tenantId = tenants.currentTenant();

        RuntimeContext context = RuntimeContext.builder()
                .userId(userId)
                .sessionId(request.sessionId())
                .put(
                        RequestIdentity.class,
                        new RequestIdentity(tenantId, userId))
                .build();

        return agents.create()
                .streamEvents(
                        new UserMessage(request.message()),
                        context)
                .filter(TextBlockDeltaEvent.class::isInstance)
                .cast(TextBlockDeltaEvent.class)
                .map(TextBlockDeltaEvent::getDelta);
    }
}

アプリケーションは、送信されたセッションが認証済みユーザーに属することを検証する必要があります。多くのシステムでは、任意のクライアント生成 ID を受け入れるのではなく、サーバーが不透明なセッション ID を発行して所有権を保存すべきです。RuntimeContext.userId が異なっていても、2 人のユーザーが同じ sessionId を使用すると、選択したストアのパーティション方法によっては会話が漏えいするおそれがあります。

単純な UI ではテキスト差分だけをストリーミングする方法が便利ですが、より豊かな API ではイベント型を保持すべきです。ブラウザーは、モデルテキスト、ツールの進捗、承認要求、復旧可能なエラー、完了を区別する必要がある場合があります。AG-UI またはアプリケーション固有のイベントエンベロープは、文字列だけのストリームより表現力があります。

ブロッキングツールを処理する #

エージェント API はリアクティブですが、アノテーション付きツールがブロッキングデータベースドライバーやレガシー HTTP クライアントを呼び出すことがあります。リアクティブ型を使っても、その操作はノンブロッキングにはなりません。次のいずれかを行ってください。

  • ノンブロッキングの依存関係と非同期ツール API を使用する。
  • ブロッキング処理を境界付きワーカープールでスケジュールする。
  • 明示的に並行性を制限した従来型のリクエストモデルを使用する。

Reactor のイベントループスレッド上で、境界のないブロッキング処理を実行しないでください。また、モデル呼び出し、ツール呼び出し、エージェント実行全体に対して個別にタイムアウトを設定します。エージェントは複数のモデル呼び出しとツール呼び出しを行う可能性があるため、総レイテンシは 1 回のモデルリクエストより大きくなります。

権限と人による承認 #

「削除前に確認する」といったプロンプト指示は有用ですが、強制にはなりません。モデルが誤解する可能性があり、取得したコンテンツがプロンプトインジェクションを試みる可能性もあり、将来のプロンプト編集で制御が弱まる可能性もあります。

AgentScope Java の権限エンジンでは、ツール呼び出しを次のように分類できます。

  • allow: 中断せずに実行する。
  • ask: 一時停止してユーザーの判断を求める。
  • deny: 操作を拒否する。

承認が必要な呼び出しでは、エージェントが確認状態を出力または返します。アプリケーションは正確な操作と引数を表示し、ユーザーの判断を記録し、その判断で実行を再開します。ヘッドレス環境では、承認が必要な操作は、黙って許可に変えるのではなく、デフォルトで拒否すべきです。

権限ルールは、通常のアプリケーション認可を補完します。

text
permission rule:
  Is this category of tool allowed in this agent flow?

OrderService authorization:
  May this authenticated user cancel this specific order?

両方のチェックが必要です。権限ルールは、テナントチェック、所有権チェック、トランザクション不変条件、データベース制約の代わりにはなりません。

メモリ、ワークスペース、サンドボックス #

これらの概念は異なる問題を解決します。

会話状態 は、セッションを継続するために必要なメッセージとエージェント状態を保持します。

長期メモリ は、会話をまたいで選択した事実や要約を保存します。保持、訂正、削除、テナント分離に関するポリシーが必要です。すべてのモデル発話を永久保存しても、メモリ戦略にはなりません。

ワークスペース は、ハーネスに計画、成果物、スキル、大規模なツール結果のための永続領域を提供します。ユーザーやツールが内容に影響を与えられる場合、ワークスペースファイルは信頼できない入力として扱ってください。

サンドボックス は、コードとコマンドの実行を分離します。異なるプロセス ID を持つだけで、ローカルサブプロセスが強力なセキュリティ境界になるわけではありません。モデルが生成したコマンドを本番で実行する場合は、リソースとネットワークを制限した、適切に強化されたコンテナ、Kubernetes、またはサポートされているリモートサンドボックスを使用してください。

マルチエージェントシステム #

AgentScope はエージェントチームとサブエージェントをサポートしますが、エージェントを複数にすれば自動的に単一エージェントより優れるわけではありません。モデル呼び出し、状態遷移、障害モード、調整コストが増加します。

次のように、明確な境界が実際に存在する場合にサブエージェントを使用します。

  • 異なるツールと権限セット
  • 専門化されたコンテキストまたはシステムプロンプト
  • 独立した並列調査
  • 個別に復元可能な長時間タスク
  • 分離を必要とする信頼境界

決定論的な順序付けには、通常の Java メソッドまたはワークフローコードを使用します。2 つの数を足すために、あるモデルから別のモデルに依頼させると、関数を呼び出すより遅く、信頼性も低くなります。

独立してデプロイされたエージェント間の通信には、サービス契約を使用します。A2A は、エージェント間のディスカバリ、メッセージ、タスク、成果物を目的としています。MCP はエージェントをツールとリソースに接続しますが、目標を自律的なリモートエージェントに委譲するものではありません。

Python AgentScope サービスとの統合 #

組織によっては、AgentScope Python で記述したエージェントをすでに運用している場合があります。Java サービスは、それをリモートシステムとして扱うべきです。

text
Spring Boot service
    -> authenticated HTTP, A2A, or messaging contract
    -> Python AgentScope service
    -> model and tools

次の項目を定義します。

  • リクエスト、イベント、成果物のスキーマ
  • プロトコルとバージョン
  • 認証とテナント伝播
  • セッション ID を作成・所有する主体
  • 冪等性の動作
  • ストリーミングと再接続の動作
  • キャンセルとタイムアウトのセマンティクス
  • エラーマッピング

Python サービスが標準的な REST API を提供する場合は、OpenAPI 契約から Java HTTP クライアントを生成します。リモートコンポーネントが長時間タスクとマルチターンのネゴシエーションを持つ独立したエージェントである場合は、A2A を使用します。Java サービスが Python の実装クラスを認識しない構成を維持してください。

組み込み Java 方式とリモート Python 方式は共存できます。たとえば、Spring Boot の注文エージェントが低レイテンシの業務処理にはローカル Java ツールを使用し、専門的な文書分析タスクを A2A 経由で Python エージェントに委譲できます。

AgentScope Java と Spring AI #

Spring AI と AgentScope Java には重複する領域がありますが、中心となる問題は異なります。

Spring AI は、移植可能なモデル API、ChatClient、Advisors、検索拡張生成、ベクトルストア、構造化出力、ツール、可観測性、MCP のための Spring ネイティブなインフラストラクチャです。既存の Spring アーキテクチャ内で主にモデル機能を必要とするアプリケーションには自然な選択肢です。

AgentScope Java は、エージェント実行ランタイムに重点を置きます。繰り返しの推論と行動、型付きライフサイクルイベント、権限、中断、ハーネスワークスペース、サブエージェント、再開可能なセッション、分散エージェント運用が対象です。

アプリケーションの主な課題に基づいて選択します。

要件開始点として考えられるもの
Spring サービスにチャット、RAG、またはツール呼び出しを追加するSpring AI
長時間実行され、中断可能で、ツールを使用するエージェントを実行するAgentScope Java
複数の AI ホストにツールを公開するMCP サーバー
独立してデプロイされたエージェントと協調するA2A

両ライブラリのモデル、メッセージ、ツールのインターフェースは互換性がありません。1 つの推論ループでフレームワークを混在させるためだけにアダプターを書かないでください。統合は、共有 Spring ビジネスサービス、MCP ツール、A2A、アプリケーション API など、安定した境界で行う方が明確です。

本番チェックリスト #

AgentScope アプリケーションを実ユーザーに公開する前に、次を確認します。

  1. すべてのエントリーポイントを認証し、信頼できるコンテキストから ID を導出する。
  2. セッション、状態、メモリ、ワークスペース、キャッシュをテナントとユーザー単位で分離する。
  3. 各エージェントには、その役割に必要なツールだけを与える。
  4. 認可をプロンプトだけでなく、ビジネスサービス内部で強制する。
  5. 金銭的、破壊的、外部への作用を伴う操作には明示的な承認を要求する。
  6. モデルが生成したコードをサンドボックス化し、ファイルシステムとネットワークへのアクセスを制限する。
  7. モデルターン、ツール呼び出し、トークン、実行時間、結果サイズ、並行性に上限を設ける。
  8. リトライが発生し得る状態変更ツールを冪等にする。
  9. 複数レプリカへスケールする前に、再開可能な状態を共有ストレージに保存する。
  10. 秘密情報と個人データをマスキングしながら、モデルとツールのイベントをトレースする。
  11. 最終的な文章回答だけでなく、完全な軌跡を評価する。
  12. キャンセル、モデル障害、ツールタイムアウト、再起動、重複配信の経路をテストする。

エージェントフレームワークは実行機構を提供しますが、どの操作が安全か、ユーザーがどのデータにアクセスできるか、モデルの回答が正しいかは決定しません。これらは引き続きアプリケーションと運用の責任です。

参考資料 #

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)