Microsoft Agent FrameworkからGitHub Copilot・Claude Codeを呼ぶ方法――.NET/Python connector実装

既存のMicrosoft Agent FrameworkアプリからGitHub CopilotまたはClaude Codeを呼び出す場合は、connectorでコーディングエージェントを生成し、.NETではAsAIFunction()、Pythonではas_tool()を使って標準のfunction toolへ変換するのが基本です。独自の分岐処理を大量に追加する必要はありません。

この方法なら、既存アプリのオーケストレーター、session、middleware、identity、OpenTelemetryを維持したまま、リポジトリ解析や修正、テスト実行だけを専門エージェントへ委譲できます。ただし、外側のエージェントとコーディングエージェントは別の実行単位です。会話履歴、権限、作業ディレクトリを自動的に共有するわけではないため、実装時には「外側のsession」と「内側のsession」を分けて設計する必要があります。(Microsoft Azure)

目次

まず結論:connector-backed agentを標準toolとして追加する

全体構成は次のようになります。

ユーザー
  ↓
既存のAgent Frameworkオーケストレーター
  ├─ 既存の業務ツール
  ├─ 検索・データベースツール
  └─ github_copilot_code または claude_code
          ↓
      connector-backed agent
          ↓
      権限ハンドラー
          ↓
      隔離されたリポジトリ/worktree/コンテナー

実装手順は次の5段階です。

  1. GitHub Copilot connectorまたはClaude connectorを追加する
  2. connectorから標準のAIAgentまたはBaseAgentを生成する
  3. .NETのAsAIFunction()、Pythonのas_tool()でtoolへ変換する
  4. 既存のtools配列へ追加する
  5. 外側と内側の両方にsession、権限、telemetryを設定する

ここで重要なのは、内側のエージェントを単なるLLM呼び出しとして扱わないことです。コーディングエージェントは、自分専用のinstructions、tools、session、ファイルアクセス権を持ちます。

外側のエージェントが確認できるのは、原則として内側のエージェントが返した最終テキストです。内側で実行したシェルコマンドやファイル操作を、外側のfunction middlewareだけですべて監視できるわけではありません。また、内側のエージェントには外側の会話履歴が自動継承されないため、必要な情報をtool引数へ明示的に含める必要があります。(Microsoft Learn)

Azure Update ID 563701で何が変わったのか

MicrosoftはAzure Update ID 563701で、Microsoft Agent Framework向けのGitHub Copilot connectorとClaude Code connectorを一般提供として案内しています。既存のAgent Frameworkアプリから、コーディングに特化したエージェントを標準的なtool surfaceとして利用しやすくなった点が中心です。(Microsoft Azure)

GitHub Copilot connectorはGitHub Copilot SDKをバックエンドとして使用し、シェル実行、ファイル操作、URL取得、MCPサーバー接続などを扱えます。.NETとPythonの公式実装例が公開されています。Claude側は、現在公開されている公式実装記事ではPythonのClaudeAgentとClaude Agent SDKを組み合わせる形が示されています。(Microsoft Learn)

GA発表とパッケージ表示が一致しない場合がある

2026年7月19日時点では、GAの案内後も、公開されているAPIリファレンスやPythonパッケージページにRC、beta、pre-releaseの表示が残っています。たとえば、.NET APIリファレンスではGitHub CopilotパッケージがRCとして表示され、PythonのClaudeパッケージにもbeta分類と--pre付きのインストール例があります。これは機能の提供状態と、各パッケージフィードの公開ラベルやドキュメント更新時期に差がある状態と考えられます。(Microsoft Learn)

実務では「GAと書かれているから常に最新版を取得する」のではなく、次の運用が安全です。

  • 検証済みのconnectorバージョンを明示的に固定する
  • packages.lock.jsonrequirements.txtuv.lockなどをリポジトリへ保存する
  • connector更新時にはsession復元、権限拒否、ファイル変更、telemetryを再テストする
  • 本番環境へ直接更新せず、検証環境とカナリア環境を経由する

GitHub Copilot connectorとClaude Code connectorの違い

項目GitHub Copilot connectorClaude Code connector
バックエンドGitHub Copilot SDKClaude Agent SDK
.NET公式NuGetパッケージとAIAgent実装あり現在の公式Claude統合記事はPython中心
Pythonagent-framework-github-copilotagent-framework-claude
主な組み込み操作シェル、ファイル、URL取得、MCPRead、Write、Bash、Glob、MCP
権限制御SessionConfigまたはpermission handler有効化するtoolとpermission_mode
sessionAgentSessionを利用sessionまたはthreadを利用
最初の検証方法コンテナー内で操作ごとに承認ReadGlobのみで開始
.NETアプリへの組み込み直接tool化しやすいPython worker経由も検討

GitHub Copilot connectorは、認証済みのGitHub Copilotランタイムを必要とします。ファイル操作やシェル実行を許可する場合、MicrosoftはDockerやDev Containerなどのコンテナー化された環境で実行することを推奨しています。

Claude connectorでは、tools=["Read", "Write", "Bash", "Glob"]のように利用可能な組み込みtoolを指定できます。最初からすべてを有効化せず、読み取り専用から段階的に権限を広げるのが安全です。(Microsoft Learn)

実装前に決めておくべき7項目

connectorを追加する前に、次の設計を確定させておくと、後から権限管理を作り直さずに済みます。

設計項目決める内容推奨例
呼び出し条件どの依頼をコーディングエージェントへ渡すかリポジトリ解析、パッチ作成、テストに限定
ワークスペースどのディレクトリを操作できるかwork itemごとの一時worktree
操作レベル読み取り、書き込み、シェル、ネットワーク初期状態は読み取りのみ
session単位何を同じ会話として継続するかtenant、user、repo、work item単位
identityどの資格情報で各runtimeを呼ぶか外側とconnector側を分離
出力形式内側のagentが何を返すか変更ファイル、コマンド、テスト、残存リスク
制限値タイムアウト、並列数、最大反復数tool単位で明示設定

特にワークスペースは、プロンプト内のパスだけで制限してはいけません。

たとえば「/workspace/task-123以外を変更しないこと」とinstructionsに書いても、OS上で別のディレクトリが見えていれば、誤操作やプロンプトインジェクションを完全には防げません。コンテナーのマウント、実行ユーザーの権限、専用worktreeによって物理的にアクセス範囲を限定します。

.NETでGitHub Copilot connectorを組み込む

パッケージを追加する

dotnet add package Microsoft.Agents.AI.GitHub.Copilot

公式例では、CopilotClientを開始した後、AsAIAgent()で標準のAIAgentへ変換します。ファイル操作やシェル実行は既定では許可されず、SessionConfigのpermission handlerで承認する構成です。(Microsoft Learn)

既存のtoolsへGitHub Copilotを追加する

次の例では、existingChatClientexistingToolsは既存アプリで構築済みとします。

using GitHub.Copilot;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

static Task<PermissionDecision> PromptPermission(
    PermissionRequest request,
    PermissionInvocation invocation)
{
    Console.WriteLine($"\n[Permission Request: {request.Kind}]");
    Console.Write("Approve? (y/n): ");

    string? input = Console.ReadLine()?.Trim().ToUpperInvariant();

    PermissionDecision decision = input is "Y" or "YES"
        ? PermissionDecision.ApproveOnce()
        : PermissionDecision.Reject();

    return Task.FromResult(decision);
}

await using CopilotClient copilotClient = new();
await copilotClient.StartAsync();

SessionConfig sessionConfig = new()
{
    OnPermissionRequest = PromptPermission,
};

AIAgent copilotAgent = copilotClient.AsAIAgent(
    sessionConfig,
    name: "CopilotRepositoryAgent",
    description:
        "指定された隔離ワークスペース内でコードを解析し、" +
        "承認された操作だけを実行するコーディングエージェント");

AgentSession copilotSession =
    await copilotAgent.CreateSessionAsync();

AIFunction copilotTool = copilotAgent.AsAIFunction(
    new AIFunctionFactoryOptions
    {
        Name = "github_copilot_code",
        Description =
            "リポジトリの解析、最小限のパッチ作成、テスト実行に使用する。"
            + "業務上の質問や一般的な文章作成には使用しない。"
            + "入力にはworkspace_id、work_item_id、制約、期待する出力を含める。"
    },
    copilotSession);

// existingToolsは既存アプリが持つAIToolの一覧
List<AITool> allTools =
[
    .. existingTools,
    copilotTool
];

AIAgent orchestrator = new ChatClientAgent(
    existingChatClient,
    name: "ApplicationOrchestrator",
    instructions: """
        github_copilot_codeは、リポジトリ内の作業だけに使用すること。
        workspace_idはユーザー入力のパスへ直接変換せず、
        サーバー側の許可済みワークスペース一覧から解決すること。
        削除、外部送信、パッケージ追加、Git pushは明示承認が必要。
        """,
    tools: allTools);

AgentSession outerSession =
    await orchestrator.CreateSessionAsync();

AgentResponse response = await orchestrator.RunAsync(
    """
    work_item_id: BUG-142
    workspace_id: ws-7f9e
    operation: analyze_and_patch

    失敗しているテストの原因を特定し、
    変更範囲が最小になる修正案を作成してください。

    出力:
    - 原因
    - 変更したファイル
    - 実行したコマンド
    - テスト結果
    - 残っているリスク
    """,
    outerSession);

Console.WriteLine(response.Text);

AsAIFunction()では、tool名とdescriptionをAIFunctionFactoryOptionsで明示できます。また、特定のAgentSessionを渡すと、複数回のtool呼び出しで内側のコンテキストを継続できます。sessionを指定しない場合は、呼び出しごとに新しいsessionが生成されるため、前回の作業内容が保持されない可能性があります。(Microsoft Learn)

明示的なsessionをsingleton登録しない

上の例は、単一の会話で利用する構成です。特定のsessionを渡したAIFunctionはステートフルになります。

MicrosoftのAPIリファレンスでも、同じsessionを複数の会話や並列tool呼び出しで共有すると、予測できない動作になる可能性があると説明されています。Webアプリでは、copilotSessioncopilotToolをアプリ全体のsingletonにせず、会話またはwork item単位で生成してください。(Microsoft Learn)

本番環境ではコンソール承認をポリシーサービスへ置き換える

Console.ReadLine()による確認はローカル検証向けです。本番環境では、次のような承認ポリシーに置き換えます。

操作推奨動作
許可済みファイルの読み取り自動承認または監査のみ
ワークスペース内のファイル更新ユーザー承認または変更量による判定
ファイル削除常に明示承認
パッケージインストールallowlistと明示承認
外部URLへのアクセスドメインallowlist
Git commit組織方針に応じて承認
Git push、PR作成、デプロイ別toolとして分離し、常に承認

コーディングエージェント自身にGit pushやデプロイまで行わせるより、パッチ作成と検証で処理を止め、その後の操作を専用toolへ分離した方が監査しやすくなります。

PythonでGitHub Copilot connectorを組み込む

パッケージを追加する

pip install agent-framework-github-copilot --pre

GitHub Copilot connectorのPython実装では、GitHubCopilotAgentが標準のBaseAgentとして利用できます。as_tool()でtool名、description、引数名を設定し、既存エージェントのtoolsへ追加します。(Microsoft Learn)

permission handlerを設定してtool化する

import asyncio

from agent_framework.github import GitHubCopilotAgent
from copilot.generated.rpc import (
    PermissionDecisionDeniedInteractivelyByUser,
)
from copilot.session import (
    PermissionHandler,
    PermissionRequestResult,
)
from copilot.session_events import PermissionRequest


async def prompt_permission(
    request: PermissionRequest,
    context: dict[str, str],
) -> PermissionRequestResult:
    print(f"\n[Permission Request: {request.kind}]")

    answer = (
        await asyncio.to_thread(
            input,
            "許可しますか? (y/n): ",
        )
    ).strip().lower()

    if answer in {"y", "yes"}:
        return PermissionHandler.approve_all(request, context)

    return PermissionDecisionDeniedInteractivelyByUser()


copilot_agent = GitHubCopilotAgent(
    instructions=(
        "You are a repository-scoped coding agent. "
        "Prefer the smallest safe change. "
        "Do not push, publish, deploy, or alter credentials. "
        "Return changed files, commands, tests, and remaining risks."
    ),
    default_options={
        "on_permission_request": prompt_permission,
        "timeout": 120,
    },
)

copilot_tool = copilot_agent.as_tool(
    name="github_copilot_code",
    description=(
        "Inspect and modify code only in the assigned isolated workspace. "
        "Use for repository analysis, minimal patches, and tests. "
        "Do not use for general questions."
    ),
    arg_name="task",
    arg_description=(
        "A task containing workspace_id, work_item_id, constraints, "
        "and the expected output."
    ),
)

# existing_clientとexisting_toolsは既存アプリ側で構築済み
orchestrator = existing_client.as_agent(
    name="application_orchestrator",
    instructions=(
        "Use github_copilot_code only for repository work. "
        "Require approval for destructive or external operations."
    ),
    tools=[*existing_tools, copilot_tool],
)

async def run() -> None:
    # outer agentがtoolを呼び出している間、
    # inner agentのruntimeを開いたままにする
    async with copilot_agent:
        result = await orchestrator.run(
            """
            work_item_id: BUG-142
            workspace_id: ws-7f9e
            operation: analyze_and_patch

            Find the cause of the failing tests.
            Create the smallest safe patch and report:
            cause, changed files, commands, tests, and remaining risks.
            """
        )

        print(result.text)

Python connectorでも、既定ではシェル、ファイルの読み書き、URL取得が許可されません。permission handlerを指定した場合に限り、要求された操作を承認できます。認証済みGitHub Copilot runtimeも必要です。(Microsoft Learn)

GITHUB_COPILOT_BASE_DIRECTORYをsandboxと誤解しない

Python connectorには、CLIパス、モデル、タイムアウト、ログレベル、CLI状態保存先などを設定する環境変数があります。

GITHUB_COPILOT_CLI_PATH
GITHUB_COPILOT_MODEL
GITHUB_COPILOT_TIMEOUT
GITHUB_COPILOT_LOG_LEVEL
GITHUB_COPILOT_BASE_DIRECTORY

ただし、GITHUB_COPILOT_BASE_DIRECTORYはCopilot CLIのsession状態や構成の保存先を指定するものです。操作可能なリポジトリ範囲をOSレベルで制限するsandboxの代わりにはなりません。実際のアクセス範囲は、コンテナーのマウントや実行ユーザー権限で制限してください。(Microsoft Learn)

PythonでClaude Code connectorを組み込む

パッケージを追加する

pip install agent-framework-claude --pre

公式のClaude統合では、agent_framework_claudeClaudeAgentを使用します。Claude Agent SDKの組み込みtoolとして、ReadWriteBashGlobなどを指定できます。(PyPI)

最初は読み取り専用で登録する

from agent_framework_claude import ClaudeAgent


claude_agent = ClaudeAgent(
    name="claude_repository_analyzer",
    instructions=(
        "You are a repository-scoped code analysis agent. "
        "Start with inspection and propose the smallest safe change. "
        "Return the cause, affected files, proposed patch, tests, and risks."
    ),
    tools=[
        "Read",
        "Glob",
    ],
)

claude_tool = claude_agent.as_tool(
    name="claude_code_analysis",
    description=(
        "Analyze source code in the assigned isolated workspace. "
        "Use for repository-wide inspection and change planning. "
        "This tool is read-only."
    ),
    arg_name="task",
    arg_description=(
        "The repository task, workspace identifier, constraints, "
        "and expected output."
    ),
)

orchestrator = existing_client.as_agent(
    name="application_orchestrator",
    instructions=(
        "Use claude_code_analysis for repository analysis. "
        "Do not request file writes or shell execution in the read-only phase."
    ),
    tools=[*existing_tools, claude_tool],
)

async def run() -> None:
    async with claude_agent:
        result = await orchestrator.run(
            """
            workspace_id: ws-7f9e
            work_item_id: BUG-142

            Find the cause of the failing integration test.
            Do not modify files.
            Return a proposed minimal patch and verification steps.
            """
        )

        print(result.text)

読み取り検証が完了した後に、必要な環境だけで次のtoolを追加します。

tools=[
    "Read",
    "Write",
    "Bash",
    "Glob",
]

公式例には、ファイル編集を自動承認するpermission_mode: "acceptEdits"もあります。ただし、機密情報を含むリポジトリや共有ワークスペースで、初期状態から自動承認を有効にするのは避けるべきです。書き込み可能な一時worktreeを作成し、変更差分を取得できる状態でのみ有効化します。(Microsoft for Developers)

なお、読み取り専用でも情報漏えいのリスクは残ります。Readしか許可していなくても、ワークスペース内に秘密鍵、.env、本番構成ファイルが見えていれば、モデルへ送信される可能性があります。読み取り権限と機密情報へのアクセス権は分けて考えてください。

.NETアプリからClaude Codeを呼びたい場合

現在公開されているMicrosoftのClaude統合記事では、PythonのClaudeAgentによる実装が示されています。利用中のパッケージフィードに正式な.NET向けClaude connectorが見つからない場合、実在を確認できないクラス名やNuGetパッケージ名を推測して実装してはいけません。(Microsoft for Developers)

その場合は、次の構成にします。

.NETの既存オーケストレーター
  ↓
認証・検証付きAIFunction
  ↓
MCPまたはHTTP
  ↓
隔離されたPython worker
  ↓
ClaudeAgent
  ↓
Claude Agent SDK

Python側の標準Agent APIには、agentをMCP serverとして公開するas_mcp_server()も用意されています。既存システムがMCPを採用しているなら、Claude workerをMCP toolとして公開し、.NET側のtool一覧へ登録する方法が自然です。(Microsoft Learn)

HTTPで接続する場合でも、.NET側では通信処理を独立したAIFunctionとして登録します。これにより、既存のfunction middleware、認可、レート制限、telemetryを維持できます。

Python workerには、少なくとも次の制御が必要です。

  • tenant_idworkspace_idの組み合わせを検証する
  • クライアントから受け取ったパスを直接使用しない
  • タイムアウトとキャンセルを伝播する
  • リクエストごとに専用workspaceを割り当てる
  • 返却値を固定スキーマにする
  • 外側のtrace IDを内側へ引き継ぐ
  • worker側でもファイル操作とシェル操作を監査する

sessionは外側・内側・workspaceの3つに分ける

コーディングエージェントを既存sessionへ統合するとき、1つのsession IDですべてを管理しようとすると、ユーザー間の履歴混在や並列実行の競合が起きやすくなります。

管理対象保持する内容推奨キー
外側のAgentSessionユーザーとの会話、業務上の意図tenant、user、conversation
内側のcoding session解析済みファイル、過去の修正、テスト結果tenant、user、repo、work item、connector
workspace実際のコードと変更差分repo、work item、実行番号

たとえば、内側のsessionは次のようなキーで管理します。

{tenant_id}:{user_id}:{repo_id}:{work_item_id}:{connector}

Agent Frameworkのsessionには、サービス側で管理される不透明なsession IDが含まれる場合があります。同じAPI資格情報やプロジェクトを複数ユーザーで利用する構成では、session IDをサーバー側で保存し、再開前に認証済みユーザーまたはtenantとの対応を検証する必要があります。(Microsoft Learn)

sessionを再利用するかどうかの判断基準

利用場面内側のsession
単発のコード説明毎回新規
依存関係の確認毎回新規でも可
修正案の作成から再テストまで同じsessionを再利用
別のissueや別リポジトリ必ず分離
複数ユーザーの同時利用必ず分離
並列tool呼び出し同じsessionを共有しない

Pythonのas_tool()で継続sessionが必要な場合

Pythonのas_tool()はtool名やdescription、引数名を指定できますが、公開されているシグネチャにはsessionやthreadを渡す引数がありません。継続的な作業が必要なら、標準Python callableをtoolとして登録し、その中で明示的にsessionを渡します。(Microsoft Learn)

# requestまたはwork itemのスコープ内で作成する
# multi-tenantアプリのグローバル変数にはしない
copilot_session = copilot_agent.create_session()


async def github_copilot_code(task: str) -> str:
    """Run an iterative repository task in a dedicated Copilot session."""
    response = await copilot_agent.run(
        task,
        session=copilot_session,
    )
    return response.text


orchestrator = existing_client.as_agent(
    instructions="Use github_copilot_code for iterative repository work.",
    tools=[
        *existing_tools,
        github_copilot_code,
    ],
)

Pythonの標準callableはfunction toolとして登録できます。実運用では、関数内でsession storeから現在のtenant、ユーザー、work itemに対応するsessionを取得します。(Microsoft Learn)

Claude側で同様の処理を行う場合は、get_new_thread()で作成したthreadを保持し、run(..., thread=thread)へ渡します。Claude Agent SDKはthreadを通じた複数ターンの継続をサポートしています。(Microsoft for Developers)

middlewareは外側と内側の二段階で設ける

Agent Frameworkには、agent実行、function呼び出し、chat clientの3種類のmiddlewareがあります。connectorをtool化した場合、外側のfunction middlewareでtool呼び出し自体を検証できます。(Microsoft Learn)

ただし、必要なのは一段階のチェックではありません。

制御地点検証する内容
外側のfunction middlewareユーザー権限、tenant、repo、work item、操作種別、利用回数
内側のpermission handler実際のファイル、コマンド、URL、書き込み、削除
OS/コンテナー見えるディレクトリ、ネットワーク、実行ユーザー、CPU・メモリ
後続のGit toolcommit、push、PR、マージ、デプロイ

外側でgithub_copilot_codeの呼び出しを許可しても、内側で実行される個々のシェル操作が自動的に承認されるわけではありません。逆に、内側のruntimeを自動承認にしていると、外側のmiddlewareでは把握できない操作が行われる可能性があります。

そのため、次の二段階で拒否できる設計にします。

  1. 外側で「このユーザーが、このリポジトリに、この種類の作業を依頼できるか」を判定する
  2. 内側で「この具体的なファイル操作またはコマンドを実行してよいか」を判定する

identityはAzure認証とconnector認証を分ける

既存アプリがAzure OpenAIやMicrosoft Foundryを使用していても、そのAzure資格情報がGitHub CopilotやClaudeへ自動的に引き継がれるわけではありません。

GitHub Copilot connectorには、認証済みのGitHub Copilot runtimeが必要です。Claude connectorもClaude Agent SDK側の資格情報と利用条件で動作します。外側のAzure tokenをconnectorへ流用したり、connector用tokenをユーザー入力やtool引数へ埋め込んだりしないでください。(Microsoft Learn)

推奨する分離は次のとおりです。

外側のLLM/Foundry
  └─ Azure側のManaged Identityまたは専用資格情報

GitHub Copilot connector
  └─ Copilot runtime側の認証

Claude connector
  └─ Claude Agent SDK側の認証

リポジトリ/workspace
  └─ 専用の実行ユーザーと最小権限

ユーザーごとの個人tokenをサーバーに長期間保存するより、組織で許可された実行環境と資格情報管理方式を定め、connector workerへ限定的に付与する方が安全です。

telemetryは外側と内側を同じtraceで追跡する

Microsoft Agent FrameworkはOpenTelemetryと統合され、trace、log、metricを出力できます。GitHub Copilot connectorのPython実装にもOpenTelemetry tracingが組み込まれています。(Microsoft Learn)

connector呼び出しでは、次の属性を記録すると障害調査がしやすくなります。

属性
connectorgithub-copilotclaude
tenant_id内部tenant識別子
workspace_idws-7f9e
work_item_idBUG-142
operationanalyzepatchtest
approval_resultapproveddenied
duration_ms実行時間
files_changed変更ファイル数
test_resultpassedfailednot_run
outcomesuccesstimeoutcancellederror

一方、ソースコード本文、秘密情報、完全なプロンプト、function引数、function結果は原則として記録しません。

Agent Frameworkでは、chat clientとagentの両方にtelemetryを設定すると、プロンプトや応答が重複して記録される場合があります。また、sensitive dataを有効化すると、プロンプト、応答、function引数、実行結果がtraceへ含まれます。sensitive dataは開発・テスト環境に限定し、本番では無効のままにしてください。(Microsoft Learn)

Tool routingを安定させるdescriptionの書き方

agent-as-toolの呼び分けは、外側のモデルによって決まります。descriptionが曖昧だと、必要な場面で呼ばれなかったり、一般的な質問でも高コストなコーディングエージェントが呼ばれたりします。(Microsoft Learn)

悪い例は次のようなdescriptionです。

コード作成を手伝うツール

これでは、コードの説明、設計相談、実ファイルの変更、デプロイのどこまで許可されるのか判断できません。

より適切なdescriptionは次のようになります。

指定された隔離ワークスペース内で、
リポジトリ解析、最小限のパッチ作成、テスト実行を行う。

業務上の一般質問、文章作成、デプロイ、Git pushには使用しない。
入力にはworkspace_id、work_item_id、operation、制約、期待する出力を含める。
削除、外部通信、依存パッケージ追加には別途承認が必要。

単一の文字列引数では足りない場合

AsAIFunction()as_tool()による標準ラッパーは、基本的に1つのqueryまたはtask文字列を内側のエージェントへ渡します。

試作段階では十分ですが、本番で厳密な認可が必要な場合は、次の項目を持つ型付きfunction toolを外側に作成してください。

{
  "workspace_id": "ws-7f9e",
  "work_item_id": "BUG-142",
  "operation": "analyze_and_patch",
  "allowed_actions": [
    "read",
    "write",
    "test"
  ],
  "expected_output": [
    "cause",
    "changed_files",
    "commands",
    "tests",
    "risks"
  ]
}

このwrapperでworkspace_idを検証し、サーバー側の安全なパスへ変換した後、内側のagentへtaskを渡します。

モデルが生成した自由形式の文字列から、直接ファイルパスやコマンドを取り出して実行する構成は避けてください。

よくある失敗と対処方法

症状主な原因対処
connectorが起動しないruntime未認証、CLIパス不正connector単体で認証と起動を確認する
toolが呼び出されないnameやdescriptionが曖昧対象タスク、禁止用途、出力を明記する
2回目の依頼で前回を忘れる内側のsessionを渡していないwork item単位でsessionを保存する
別ユーザーの履歴が混ざるsessionをsingleton共有tenant、user、repo、work itemで分離する
並列実行で結果が不安定同じ明示sessionを同時利用呼び出しごとに分離するか直列化する
外側で許可した後に危険なコマンドが動く内側のpermission handlerがない外側と内側で二重に承認する
想定外のファイルを読むワークスペースが広すぎる専用worktreeと限定マウントを使う
PythonのClaude実装を.NETクラスとして書いてしまう未確認のAPI名を推測パッケージを確認し、なければworker経由にする
更新後にビルドが壊れるRC/betaを無条件更新バージョンとlock fileを固定する
traceにコードや秘密情報が残るsensitive dataを有効化本番では無効化し、属性のみ記録する
すべての操作が自動承認されるapprove_allや自動編集を本番利用操作別の承認ポリシーへ置き換える

本番投入前のチェックリスト

次の順番で検証すると、安全性と実装負荷のバランスを取りやすくなります。

  1. 廃棄可能なサンプルリポジトリを用意する
  2. 読み取り専用のconnector-backed toolを追加する
  3. tool routingが期待どおりか評価する
  4. work itemごとに専用worktreeまたはコンテナーを作る
  5. 書き込みを追加し、変更差分を必ず保存する
  6. テスト実行を追加し、コマンドと終了コードを記録する
  7. 削除、ネットワーク、パッケージ追加を拒否するテストを行う
  8. tenantとユーザーを変えてsession分離を確認する
  9. timeout、キャンセル、並列実行を確認する
  10. sensitive dataを無効にしたtelemetryを確認する
  11. 検証済みバージョンを固定する
  12. 一部の利用者またはリポジトリから段階的に展開する

最低限、次の条件を満たすまでは本番のリポジトリへ接続しない方が安全です。

  • 許可されたworkspace外を読み書きできない
  • 承認処理が停止した場合は拒否側へ倒れる
  • 異なるユーザー間でsessionが共有されない
  • tool呼び出しと承認結果をtraceで追跡できる
  • 変更ファイルとテスト結果が構造化されて返る
  • connectorのバージョンが固定されている
  • Git pushやデプロイが別の承認済みtoolへ分離されている

まとめ

Microsoft Agent FrameworkからGitHub CopilotやClaude Codeを呼び出す際は、connector独自の分岐をアプリ全体へ広げるのではなく、connector-backed agentを標準toolへ変換して既存オーケストレーターへ登録します。

.NETではGitHub Copilot agentをAsAIFunction()で変換し、PythonではGitHub CopilotやClaudeのagentをas_tool()で変換できます。これにより、既存のsession、middleware、identity、telemetryを利用しながら、コーディング処理だけを専門agentへ委譲できます。

ただし、内側のsessionと権限は外側から独立しています。最初は廃棄可能なリポジトリ、読み取り専用tool、隔離workspaceで動作を確認してください。その後、書き込み、シェル、ネットワークを操作別の承認付きで段階的に追加するのが、最も安全で修正しやすい導入手順です。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次