Bedrockアプリケーション推論プロファイル利用時にClaude Codeのbuilt-in subagentが403エラーになる問題と対処法

Bedrockアプリケーション推論プロファイル利用時にClaude Codeのbuilt-in subagentが403エラーになる問題と対処法

2026.04.14

はじめに

Claude Codeを企業に導入する際に、Bedrock経由で使うケースがあります。API利用料をAWSの請求に統合でき、通信先がAWSに閉じる点や、IAMによるアクセス制御・CloudTrailによる監査ログなど、既存のAWSの管理基盤に乗せられるメリットがあります。

さらに、個人ごとの利用料を把握したいというモチベーションが出てくると、アプリケーション推論プロファイルを作成してユーザー単位でトラッキングする構成が必要になります。

https://dev.classmethod.jp/articles/shuntaka-cdk-application-inference-profile-creation-cline-utilization/

このユースケースで、Claude Codeで一部環境変数を設定しないとbuilt-inのsubagentが起動しないケースがありますので、問題詳細と解決方法をご紹介します。

なお、本記事はClaude Code 2.1.104 で確認しています。

Built-in subagents

Claude Codeの公式ドキュメントは以下なのでこちらをご覧ください。

https://code.claude.com/docs/ja/sub-agents#組み込みサブエージェント

/agents から tabを押して、Libraryをみると内容が確認できます。

CleanShot 2026-04-14 at 17.23.50@2x

私がよく使うのは claude-code-guide です。

Claude CodeにClaude Codeの設定をさせる場合かなり精度が悪いです。具体例を出すとClaude CodeのRulesやSkillをコードベースに初回作成しようとした場合、他のAIエージェントの仕様と混ざるのか、ハルシネーションし設定が読み込まれないケースがありました。そこで前述の claude-code-guide が有効です。

以下の画像のような形でsubagentsの呼び出しを確認することができます。

CleanShot 2026-04-14 at 17.28.25@2x

claude-code-guideを明示的に指定しているのは、自然に発火するケースが少ないためです 😭

呼び出されている中身をみると、subagentからそれっぽい内容が回答されていることが確認できます。

CleanShot 2026-04-14 at 17.38.12@2x

問題の事象

以下はアプリケーション推論プロファイルをメンバーごとに作成するCDKコードです。

  • config.ts: チーム名とメンバー(名前・メールアドレス)の一覧を定義
  • main-stack.ts: configの定義をもとに、メンバーごとに以下のリソースを作成
    • アプリケーション推論プロファイル(クロスリージョン推論プロファイルをソースに指定)
    • IAMユーザーとアクセスキー
    • 認証情報をSecrets Managerに格納
設定ファイル(config.ts)
type Config = {
  teams: {
    name: string;
    members: {
      name: string;
      email: string;
    }[];
  }[];
};

export const config: Config = {
  teams: [
    {
      name: "olympus",
      members: [
        { name: "zeus", email: "zeus@example.com" },
        { name: "athena", email: "athena@example.com" },
        { name: "apollo", email: "apollo@example.com" },
      ],
    },
    {
      name: "asgard",
      members: [
        { name: "thor", email: "thor@example.com" },
        { name: "freyja", email: "freyja@example.com" },
        { name: "baldur", email: "baldur@example.com" },
      ],
    },
  ],
};
CDKスタック(main-stack.ts)
import * as bedrock from "@aws-cdk/aws-bedrock-alpha";
import * as cdk from "aws-cdk-lib";
import * as iam from "aws-cdk-lib/aws-iam";
import * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
import { pascalCase } from "change-case";
import type { Construct } from "constructs";
import { config } from "./config.js";

export class MainStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const model = bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_4_6;

    const cris = bedrock.CrossRegionInferenceProfile.fromConfig({
      geoRegion: bedrock.CrossRegionInferenceProfileRegion.US,
      model,
    });

    for (const team of config.teams) {
      for (const member of team.members) {
        const prefix = `${team.name}-${member.name}`;
        const idPrefix = pascalCase(prefix);

        const aip = new bedrock.ApplicationInferenceProfile(this, `${idPrefix}Aip`, {
          applicationInferenceProfileName: `sonnet4-${team.name}-${member.name}`,
          modelSource: cris,
          description: `${team.name}-${member.name}`,
          tags: {
            team: team.name,
            name: member.name,
            email: member.email,
          },
        });

        const user = new iam.User(this, `${idPrefix}User`, {
          userName: `${prefix}-bedrock`,
        });
        aip.grantInvoke(user);
        user.addToPolicy(
          new iam.PolicyStatement({
            actions: ["bedrock:InvokeModelWithResponseStream"],
            resources: [aip.inferenceProfileArn],
          }),
        );

        const accessKey = new iam.AccessKey(this, `${idPrefix}Key`, { user });

        new secretsmanager.Secret(this, `${idPrefix}Creds`, {
          description: `Bedrock API creds for ${team.name}/${member.name}`,
          secretObjectValue: {
            AccessKeyId: cdk.SecretValue.unsafePlainText(accessKey.accessKeyId),
            SecretAccessKey: accessKey.secretAccessKey,
          },
        });
      }
    }
  }
}
デプロイ後、メンバーの認証情報と環境変数を取得するスクリプト
export PROFILE_NAME="sonnet4-olympus-zeus"
export ARN=$(aws bedrock list-inference-profiles --region us-west-2 --type-equals APPLICATION --query "inferenceProfileSummaries[?inferenceProfileName=='${PROFILE_NAME}'].inferenceProfileArn" --output text)
export MEMBER_KEY=$(echo "${PROFILE_NAME#sonnet4-}" | awk -F- '{for(i=1;i<=NF;i++) printf toupper(substr($i,1,1)) substr($i,2)}')
export SECRET_ID=$(aws secretsmanager list-secrets --region us-west-2 --query "SecretList[?starts_with(Name, '${MEMBER_KEY}Creds')].Name" --output text)
export CREDS=$(aws secretsmanager get-secret-value --secret-id "${SECRET_ID}" --region us-west-2 --query SecretString --output text)
echo "export AWS_ACCESS_KEY_ID=$(echo "${CREDS}" | jq -r .AccessKeyId)"
echo "export AWS_SECRET_ACCESS_KEY=$(echo "${CREDS}" | jq -r .SecretAccessKey)"
echo "export AWS_REGION=us-west-2"
echo "export CLAUDE_CODE_USE_BEDROCK=1"
echo "export ANTHROPIC_MODEL=${ARN}"
echo "export ANTHROPIC_SMALL_FAST_MODEL=${ARN}"
echo "export ANTHROPIC_DEFAULT_HAIKU_MODEL=${ARN}"
echo "export ANTHROPIC_DEFAULT_SONNET_MODEL=${ARN}"
echo "export ANTHROPIC_DEFAULT_OPUS_MODEL=${ARN}"

上記の出力からANTHROPIC_MODELまでの環境変数を設定してClaude Codeを起動します。

export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=yyy
export AWS_REGION=us-west-2
export CLAUDE_CODE_USE_BEDROCK=1
export ANTHROPIC_MODEL=arn:aws:bedrock:us-west-2:111111111111:application-inference-profile/ffffffffffff

テストメッセージを送信し、アプリケーション推論プロファイルが動作していることが確認できます。

CleanShot 2026-04-14 at 17.52.38@2x

claude-code-guideを使ってみます。

回答は返ってきましたが、subagent呼び出しでエラーになっていることがわかります。

CleanShot 2026-04-14 at 17.58.55@2x

Ctrl-oで内容を展開するとsubagentがAPI呼び出しをして403エラーになっていることが分かります。それだけでなくこのsubagentの回答を待つのに3分かかっています。バックグラウンドに回すことも可能ですが、ユーザーがコマンドを押さない限り無駄な時間を過ごすことになります。エラーになったことは回答として返ってくるので、気づかず時間を溶かしていたということはなさそうです。

CleanShot 2026-04-14 at 18.01.50@2x

この原因は、subagentが特定モデルに固定されているためだと考えられます。画像の通りclaude-code-guideはhaikuです。後述する環境変数を設定していないとsubagentは、haikuのシステム定義推論プロファイルを呼び出してしまい、権限がなくエラーになっているものと推測されます。

CleanShot 2026-04-14 at 17.23.50@2x

解決方法

ANTHROPIC_SMALL_FAST_MODELANTHROPIC_DEFAULT_HAIKU_MODELANTHROPIC_DEFAULT_SONNET_MODELANTHROPIC_DEFAULT_OPUS_MODEL にもアプリケーション推論プロファイルのARNを設定します。

export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=yyy
export AWS_REGION=us-west-2
export CLAUDE_CODE_USE_BEDROCK=1
export ANTHROPIC_MODEL=arn:aws:bedrock:us-west-2:111111111111:application-inference-profile/ffffffffffff
export ANTHROPIC_SMALL_FAST_MODEL=arn:aws:bedrock:us-west-2:111111111111:application-inference-profile/ffffffffffff
export ANTHROPIC_DEFAULT_HAIKU_MODEL=arn:aws:bedrock:us-west-2:111111111111:application-inference-profile/ffffffffffff
export ANTHROPIC_DEFAULT_SONNET_MODEL=arn:aws:bedrock:us-west-2:111111111111:application-inference-profile/ffffffffffff
export ANTHROPIC_DEFAULT_OPUS_MODEL=arn:aws:bedrock:us-west-2:111111111111:application-inference-profile/ffffffffffff

claude-code-guide が正しく完了していることがわかります🥳🥳🥳
CleanShot 2026-04-14 at 18.13.23@2x

最後に

かなり重箱の隅をつつくネタですが、ご支援先でこの事象に遭遇したので記事にしました。この記事を書く過程でCLAUDE_CODE_USE_BEDROCK=1にすれば、デフォルトでシステム定義プロファイルにフォールバックされるようになっていることも確認しました。CloudShellからCLAUDE_CODE_USE_BEDROCK=1設定だけでClaude Codeが呼び出せるなど、Bedrock連携周りが充実してきたなと感じました。インストールもワンコマンドでバイナリですしね。。何か良いユースケースがあれば教えてください😆😆😆

この記事をシェアする

関連記事