llm-to-bedrock について
llm-to-bedrockは、OpenAI、Gemini、Anthropicを使うAIワークロードをAmazon Bedrockへ移行するエージェントスキルです。評価は別途必要なgcp-to-awsに委ね、その成果物を使ってSDKを書き換えます。
主な機能
- 01OpenAI、Gemini、Anthropicからの移行
- 02gcp-to-awsへの評価委任
- 03評価結果に基づくBedrock SDKの書き換え
- 04前提条件と評価成果物の確認
活用シーン
- 01AIワークロードのAmazon Bedrockへの移行
- 02評価後のSDK書き換え
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ awslabs/ startups --skill llm-to-bedrockインストール後、Claude Code で/llm-to-bedrockを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/helpers/bedrock-known-fixes/bedrock-known-fixes.mdreferences/helpers/bedrock-known-fixes/references/bedrock-iam-inference-profile.mdbedrock-inference-profile-model-id.mdbedrock-response-key-casing.mdbedrock-vision.mdbedrock-vision.py.templatereferences/helpers/behavior-delta-detection/behavior-delta-detection.mdreferences/helpers/behavior-delta-detection/references/gemini-to-bedrock.mdopenai-to-bedrock.mdreferences/helpers/dependency-conflict-resolution/dependency-conflict-resolution.mdreferences/helpers/resolve-bedrock-model-id/resolve-bedrock-model-id.mdreferences/helpers/run-source-model-baseline/run-source-model-baseline.mdscripts/bedrock_pricing.pyiam_policy.pyimage_input.pypreflight_bedrock.pypyproject.tomlrender_report.pyresolve_source_model.pysource_baseline.pytest_bedrock_pricing.pytest_delta_reference_schema.pytest_iam_policy.pytest_image_input.pytest_preflight_bedrock.pyscripts/schemas/analysis.jsondelta-decisions.jsoneval.jsoningestion.jsonrewrite.json詳細
Bedrock への移行(評価+実行)
単一コマンドで行う AI 移行:OpenAI / Gemini / Anthropic → Amazon Bedrock。
このスキルと併せて gcp-to-aws スキルをインストールする必要があります。 このスキルには単独で実行できる評価の実装はありません。以下のフェーズ A では、評価を全面的に gcp-to-aws に委任するスキル間呼び出しを行います。gcp-to-aws が見つからない場合に、このスキル自体で評価を実行する代替手段はありません。このスキルだけをインストールした場合(例:単一スキルの npx skills add)、使用する前に gcp-to-aws もインストールしてください。
スキルのベースディレクトリは、ハーネスが読み込み時に出力する「Base directory for this skill: X」の行で示されます。これを <SKILL_BASE> と呼びます。派生パスは次のとおりです。
$SCRIPTS=<SKILL_BASE>/scripts$HELPERS=<SKILL_BASE>/references/helpers(以前はヘルパースキルでしたが、現在はリファレンスです)
ステップ 0 — 前提条件の確認
0a. uv が利用可能か確認する
uv --version 2>/dev/null || echo "MISSING"
見つからない場合:「まず uv をインストールしてください。公式のインストールガイドを参照してください:https://docs.astral.sh/uv/getting-started/installation/(例:`brew install uvまたはpipx install uv`)。」停止します。
0b. gcp-to-aws の兄弟スキルがインストールされていることを確認する
以下のフェーズ A では、Assess ステップ全体を Skill ツール経由で gcp-to-aws スキルに委任します。このスキルには、代替として利用できる Assess ロジックはありません。gcp-to-aws は別個のスキルであり、このスキルに同梱されているわけではありません。単一スキルのインストール(例:npx skills add ... --skill llm-to-bedrock)では、自動的に一緒にインストールされません。このデプロイでは実行できない Assess フェーズをユーザーに約束してしまう前に、今すぐ確認してください。
[ -f "<SKILL_BASE>/../gcp-to-aws/SKILL.md" ] && echo GCP_TO_AWS_PRESENT || echo GCP_TO_AWS_MISSING
これは、<SKILL_BASE>(上記で定義)を基準とした兄弟ディレクトリを確認します。そのため、ネイティブのプラグインインストールでも npx skills add --skill '*' でも機能します。どちらの場合も、gcp-to-aws はこのスキル自身のディレクトリの兄弟として配置されます。${CLAUDE_PLUGIN_ROOT} には依存しません。
-
GCP_TO_AWS_PRESENT→ ステップ 1 に進みます。 -
GCP_TO_AWS_MISSING→ ここで停止し、先に進まないでください。 ユーザーに次のように伝えます。「この移行には、
gcp-to-awsスキルをこのスキルと一緒にインストールする必要があります。このスキルがコードのスキャン、AI ワークロードの検出、Bedrock モデルの設計を担当します。これがないと、私自身ではその部分を実行できません。次のコマンドでインストールしてください。npx skills add https://github.com/aws/agent-toolkit-for-aws/tree/main/plugins/aws-startup-advisor --skill gcp-to-aws --agent <agent>(このスキルで使ったものと同じ--agentおよび--global/プロジェクトのスコープを指定してください)。エージェントを再起動してから、もう一度移行を依頼してください。なお、このプラグインは
aws/agent-toolkit-for-awsに移転しており、現在インストールされているコピーはメンテナンスされていません。上記のコマンドでは、新しい場所からインストールできます。プラグイン全体を新しい場所に移行するには、そこから再インストールしてください。詳細は https://github.com/aws/agent-toolkit-for-aws をご覧ください。」代替手段として Assess フェーズを自分で実行しないでください。以下のフェーズ A では、Assess ロジックは
gcp-to-awsのみに存在すると明示されています。ここで再実装すると、時間の経過とともに、そのスキルの Discover/Clarify/Design ロジックと同期が取れなくなります。このスキルに単独で実行できる Assess はありません。この確認は、別の動作を可能にするためではなく、早い段階で明確に失敗させるためのものです。
また、フェーズ A で gcp-to-aws を呼び出すには、エージェントが Skill ツール(名前を指定したスキル間呼び出し)に対応している必要があります。 Claude Code での対応は確認済みですが、npx skills によるインストールに対応したすべてのエージェント(Cursor、Codex など)で検証されているわけではありません。そうしたエージェントを使っていて、これが失敗する場合は、それが原因である可能性が高いです。フェーズ A の A1 ステップで Skill ツールの呼び出しが失敗する場合、またはエージェントにそのような仕組みがない場合、このスキルにはやはり代替手段がありません。このエージェントでは gcp-to-aws を自動的に連携実行できないことを率直にユーザーに伝え、まずユーザー自身で gcp-to-aws を直接呼び出すよう依頼してください(例:「自分の AI ワークロードを AWS に移行して」)。Discover から Design までを実行し(判断パックを受け入れるだけで十分です。インフラ用の Terraform を生成する必要はありません)、その後、Assess の成果物が準備できたら(判断パックが完成しているか、generate が completed になっていることを A2 で確認してから)、このスキルに戻り、SDK の書き換えを続けます。これはエージェントの機能不足に対する手動の二段階の回避策であり、自動の代替手段ではありません。このスキルが「対応する」とユーザーに伝えないでください。
ステップ 1 — ソースコードのパスを収集する
$ARGUMENTS にパスが含まれている場合は、それを $REPO として使用します。それ以外の場合は AskUserQuestion を使用します。
「ソースコードの場所を教えてください。ローカルパスまたは GitHub URL を入力してください。」
GitHub URL の場合は、一時ディレクトリに git clone し、そのパスを $REPO として使用します。
$REPO のチェック:
-
Git ルートのチェック(解決済みパスを比較します。macOS では
/tmpは/private/tmpに解決されるため、 生の文字列を比較すると誤検知が発生します):[ "$(git -C <REPO> rev-parse --show-toplevel 2>/dev/null)" = "$(cd <REPO> && pwd -P)" ] && echo GIT_ROOT_OK || echo GIT_ROOT_MISMATCHGIT_ROOT_OK→ 続行します。GIT_ROOT_MISMATCHで、コマンドがエラーになった場合(Git リポジトリではない)→ 成果物は Git ブランチであるため、パスには Git リポジトリを指定する必要があることをユーザーに伝え、再度尋ねます。GIT_ROOT_MISMATCHだがリポジトリ内である場合(ユーザーがサブディレクトリを指定した)→ AskUserQuestion: 「リポジトリのルートを使用する」(推奨)/「このサブディレクトリで続行する」/「中止する」。
-
作業ツリーの変更チェック:
git -C <REPO> status --porcelain未コミットの変更がある場合は、それらを表示して AskUserQuestion を実行します:「このまま続行する」または「先に整理する」。
以降のすべてのステップで使用する $REPO を記録します。
フェーズ A — 評価(必須:gcp-to-aws スキルに委任する)
重要:Skill ツールを使用して aws-startup-advisor:gcp-to-aws(同じプラグイン内の関連スキル)を必ず呼び出してください。評価フェーズを自分で実行してはいけません。ソースコードを読んだり、AI SDK を検出したり、Clarify の質問を手動で尋ねたりしないでください。評価フェーズ全体は gcp-to-aws スキルが処理します。スキルを呼び出し、完了を待つだけです。
A1 — 評価スキルを呼び出す
スキル名 aws-startup-advisor:gcp-to-aws を指定して Skill ツールを呼び出します。
呼び出す前に、ユーザーに次のように伝えます:
「これから gcp-to-aws 評価スキルを呼び出し、AI ワークロードを特定して Bedrock への移行を設計します。いくつか質問されますので、回答してください。(スキル名が
gcp-to-awsであることに戸惑わないでください。ここでは、GCP やインフラストラクチャ要素を含まない、AI/LLM のみの移行にも対応する機能を使用します。)」
Skill ツールを呼び出すと、gcp-to-aws スキルの指示がコンテキストに読み込まれます。その指示に正確に従ってください。指示に沿って、意思決定パックが完成するまで、Discover、Clarify、Design、Estimate の各フェーズが進みます。スキャン対象のソースコードは $REPO にあります。gcp-to-aws に Generate(インフラ Terraform)フェーズを実行させる必要はありません。これは任意であり、この SDK の書き換えで読み取られる成果物は生成されないため、意思決定パックの段階で停止すれば十分です(A2 で準備状況を確認します)。
Discover でこの実行の .phase-status.json を作成する際は、owning_skill(GCP_TO_AWS のままにします)の隣に "initiated_by": "LLM_TO_BEDROCK" を記録する必要があります。この実行は llm-to-bedrock によって開始されたものであり、テレメトリでこの値を使って開始元を識別します。
gcp-to-aws スキルの実行に関する重要なコンテキスト:
- ソースコードは
$REPOにあります。スキルから GCP ソースを尋ねられた場合やファイルをスキャンする場合は、ここを指定してください - これは AI/LLM ワークロードの移行です。目標は AI の経路です
$REPOに Terraform/IaC ファイルが実際に存在しない限り、IaC の検出はスキップしてください- ユーザーから請求データが提供されない限り、請求データの検出はスキップしてください。ソースプロバイダーが
OpenAI の場合、スキルから代わりに OpenAI Admin API による使用状況の検出を提案されることがあります
(
discover-openai-api.md— 読み取り専用、同意が必要で、Admin キーの Usage を Read に設定する必要があります)。これを受け入れると、手動で CSV をエクスポートしなくても、Estimate で実際の支出額とトークン量を把握できます
A2 — Assess の完了を待つ
gcp-to-aws スキルはステートマシンです。各フェーズの完了後、停止して次の呼び出しを待つことがあります。このスキルが必要とするのは Assess の成果物(Design の aws-design-ai.json、Discover の ai-workload-profile.json、Clarify の preferences.json)だけです。Generate が生成するもの(Terraform、MIGRATION_GUIDE.md、migration-report.html)は読み取りません。これらの成果物は Design の完了時点ですべてディスク上にあるため、AI/SDK のみを書き換える場合、gcp-to-aws にインフラの Generate フェーズを実行させる必要はありません。以下のチェックでは、次のいずれかに該当すると(記載順に)assess-ready を出力します。
- Design 完了+成果物あり —
phases.design == "completed"かつaws-design-ai.jsonが存在する。これが AI パスの確かな根拠です。Design 自体の完了条件を通過しているため、モデルマッピングは作成途中ではなく、確定したものです。(存在するだけでは不十分です。design-ai.mdが JSON を書き込み、Discover と Clarify もそれぞれのファイルをさらに早い段階で書き込むため、いずれもdesign.mdがphases.designを設定する前に作成されます。そのため、「3 つのファイルがすべて存在する」だけでは Design の途中で判定が成立してしまいます。phases.design == "completed"を必須にすることで、この早すぎる判定を防ぎます。)これは、gcp-to-aws/SKILL.mdのlegacy-generateとの後方互換状態にも対応しています。この状態に到達できるのは Design の完了後に限られるため、すでにphases.design == "completed"になっています。 - Decide 完了 —
current_phase == "complete"かつrun_mode == "decide"かつphases.generate == "pending"かつDECISION.mdがディスク上に存在する(通常の AI パスの終了状態)。 - Generate 完了 —
phases.generate == "completed"(ユーザーがインフラの生成も選択した場合)。
Workshop ガード(上記 3 条件すべてに適用): phases.workshop == "in_progress" の間は、いずれの条件も信頼できません。IaC と AI を組み合わせた実行では、design.md の内側のワークショップパスが phases.design == "completed" を明示的に維持する一方、workshop-refresh.md が価格を再計算するために preferences を更新し、Design の成果物を書き換えています。そのため、条件 1(および phases.design が戻ることはないため、そこから派生する条件 2 と 3)では、aws-design-ai.json が古いリージョン/モデルマッピングと新しいものの間にある状態で assess-ready が読み取られる可能性があります。phases.workshop が "in_progress" になるのは、このループの実行中だけです(workshop.md § Entry step 3。終了/辞退時には "completed" に戻ります)。したがって、これは永続的な状態ではなく、実際に起こり得る短時間の中断ウィンドウです。上記 3 条件の結果にかかわらず、phases.workshop == "in_progress" は not-ready として扱い、以下の上限に達するまで再ポーリングしてください。
最新の実行ディレクトリのみを対象に進行状況を確認します(古い .migration/ の実行には、古いステータスが含まれている場合があります)。
MIGRATION_DIR=$(ls -td "$REPO/.migration"/*/ 2>/dev/null | head -1)
# Stdlib-only JSON read — no boto3, so bare python3 is fine here (no pinned env needed).
# Emit one token: assess-ready / not-ready / no-status-file. Ground truth is the Assess the AI
# path actually consumes (see the three conditions above); the phase-status tuples are fallbacks.
python3 - "$MIGRATION_DIR" <<'PY' 2>/dev/null || echo "no-status-file"
import json, os, sys
d = sys.argv[1]
if not d:
print("no-status-file"); sys.exit()
def has(f): return os.path.exists(os.path.join(d, f))
try:
s = json.load(open(os.path.join(d, ".phase-status.json")))
except Exception:
# No readable status file, but the design artifact alone is not trusted (may be mid-Design);
# without the status we cannot confirm Design's gate passed.
print("no-status-file" if not has("aws-design-ai.json") else "not-ready"); sys.exit()
ph = s.get("phases", {})
# An active workshop reprice is actively rewriting aws-design-ai.json/aws-design.json between an
# old and a new mapping (workshop-refresh.md), while design.md's inner-workshop path leaves
# phases.design == "completed" throughout — so none of the three readiness conditions below are
# trustworthy while this holds. Checked first and short-circuits to not-ready.
if ph.get("workshop") == "in_progress":
print("not-ready"); sys.exit()
# phases.design == completed means Design's completion gate passed, so aws-design-ai.json is
# final (not mid-authoring). This also covers the legacy-generate state, which is only reachable
# after Design. Do NOT accept a bare "all three files exist" — Discover/Clarify write their two
# files early, and design-ai.md writes aws-design-ai.json BEFORE the gate, so three-files-present
# fires mid-Design (the early-fire case). A3 remains the artifact-completeness backstop.
design_done = ph.get("design") == "completed" and has("aws-design-ai.json")
generate_done = ph.get("generate") == "completed"
decide_done = (
s.get("current_phase") == "complete"
and s.get("run_mode") == "decide"
and ph.get("generate") == "pending"
and has("DECISION.md")
)
print("assess-ready" if (design_done or generate_done or decide_done) else "not-ready")
PY
assess-ready→ A3 に進みます(インフラの Generate が実行されたかどうかにかかわらず、Assess は完了しています)。A3 では Execute が読み取る前に、対象のファイルが揃っていることを改めて確認します。not-ready/no-status-file→ スキルを再実行する必要があります。Skill ツールを使ってaws-startup-advisor:gcp-to-awsを再度呼び出してください。前回の続きから再開します。(Generate まで実行させる必要はありません。decision pack で停止すれば十分です。)
上限:再呼び出しは最大 6 回です。 6 回後も not-ready の場合は停止し、最後のステータス出力をユーザーに提示してください。Assess スキルが停止しており、手動での対応が必要です。さらにループを続けてもコンテキストを消費するだけです。
A3 — Assess の出力を確認する
$MIGRATION_DIR(作成された .migration/<MMDD-HHMM>/ ディレクトリ)を探します。
ls -td "$REPO/.migration"/*/ 2>/dev/null | head -1
$MIGRATION_DIR に次のファイルがすべて3つ存在することを確認します(Phase B ではすべて読み込みます)。
aws-design-ai.json(モデルのマッピング+アーキテクチャ)ai-workload-profile.json(検出されたワークロード)preferences.json(Clarify で指定されたユーザー設定)
3つのうちいずれかが見つからない場合、Assess で AI パスが正しく完了していません。不足しているファイル名を示し、エラーを表示して停止します。(A2 はデザインファイルと phases.design だけで assess-ready を報告できるようになったため、この手順で、Execute が読み込む前に Phase B に必要な残りの成果物が実際に存在することを確認します。)
Phase B — Execute の準備
B1 — Assess の出力を読み込む
$MIGRATION_DIR/aws-design-ai.json を読み込み、次の値を抽出します。
ai_architecture.bedrock_models[]→{source_model, aws_model_id, use_case}の配列- すべての
aws_model_idの値を$TARGET_MODELS(配列)にまとめます。それぞれのuse_caseも保持してください。プリフライトスクリプトは各モデルを適切な API で自動的にテストします(チャットには Converse、埋め込みには InvokeModel)。ただし、評価ツールによる品質スコアリングの対象はチャットモデルのみです。埋め込みのターゲットには、形式と次元の検証のみが行われます。
$MIGRATION_DIR/ai-workload-profile.json を読み込み、次の値を抽出します。
summary.ai_source→ ソースプロバイダー
$MIGRATION_DIR/preferences.json を読み込み、次の値を抽出します。
design_constraints.target_region→$REGION(指定がない場合のデフォルトはus-east-1)
検証: aws-design-ai.json に ai_architecture.bedrock_models[] 配列がない場合、または配列が空の場合は、停止します。「Assess の出力が不完全です — モデルのマッピングがありません。」
B2 — AWS アイデンティティの確認
aws sts get-caller-identity 2>&1
コマンドが失敗した場合(認証情報がない、SSO トークンの有効期限が切れているなど)は、エラーを表示し、aws configure または aws sso login を実行するようユーザーに伝えます(このセッションで実行するには ! aws sso login と入力するよう案内します)。その後、B2 を再実行します。アイデンティティを確認できるまで先へ進まないでください。
成功したら、AskUserQuestion を使って Account、Arn、UserId を表示します。 「この AWS アイデンティティを Bedrock の呼び出しに使用します。よろしいですか?」
選択肢:
- はい、このアイデンティティを使用する → 続行
- 別の AWS プロファイルを使用する → 使用するプロファイルを尋ね、
$AWS_PROFILE_CHOICEとして記録し、B2 をaws sts get-caller-identity --profile $AWS_PROFILE_CHOICEとして再実行して、再確認します。AWS_PROFILEのエクスポートには頼らないでください。環境変数は Bash ツールの呼び出し間やワークフローのサブエージェントには引き継がれません(B3 を参照)。代わりに、選択したプロファイルをすべての場所で明示的に渡します。すべての AWS CLI 呼び出しで--profileを指定し、B4 のプリフライトコマンドとワークフローの引数(awsProfileフィールド)内では先頭にAWS_PROFILE=$AWS_PROFILE_CHOICEを付け、サブエージェントでも同様に指定できるようにします。
リージョンも確認します。「Bedrock のリージョンは $REGION です。よろしいですか、それとも変更しますか?」
B3 — ソース API キー(任意)
まず、アーティファクトディレクトリを作成し、直ちにそのディレクトリを Git の追跡対象から除外してください。キーが存在する前に実行することで、リライターが実行される前にユーザーが中断した場合でも、秘密情報が追跡対象の作業ツリーに置かれることはありません。
mkdir -p "$REPO/.saws-migrate" && printf '*\n' > "$REPO/.saws-migrate/.gitignore"
B1 のソースプロバイダーに基づいて $KEY_ENV_VAR を決定します(ベースラインスキルのパーサーが想定する環境変数名です。NAME= のプレフィックスがないキーだけでは解析されません)。
openai→OPENAI_API_KEYanthropic→ANTHROPIC_API_KEYgoogle/gemini→GEMINI_API_KEY
キーをこの会話に入力してはいけません(絶対厳守)。 チャットにキーを貼り付けるようユーザーに求めないでください。また、その値をコマンド、質問、出力に表示、cat、展開してはいけません。エージェントが扱うのはファイルパスだけです。ユーザーが求められていないのにチャットへキーを貼り付けた場合は、使用せず、そのキーが会話の記録に残ったことを伝え、キーのローテーションを勧めてから、以下のいずれかの方法で続行してください。
まず、キーがすでにシェル環境に存在するかを確認します(Bash を呼び出すたびにユーザーのプロファイルが読み込まれるため、プロファイルでエクスポートされたキーはすべての呼び出しから参照できます)。
POSIX 互換です。printenv は bash と zsh のどちらでも動作します(${!VAR} による間接参照は bash 専用で、zsh ではエラーになります)。次のコマンドはキーの有無だけを出力し、値は出力しません。
[ -n "$(printenv "$KEY_ENV_VAR")" ] && echo ENV_KEY_PRESENT || echo ENV_KEY_ABSENT
AskUserQuestion: 「ソースモデル用の API キー(例:GPT-4o 用の OpenAI キー)をお持ちですか? キーを提供すると、品質を横並びで比較できます。提供しない場合、評価は絶対評価のみになります。」
選択肢(ENV_KEY_PRESENT の場合に限り、最初の選択肢を提示します):
-
環境にすでに設定されている
$KEY_ENV_VARを使う → 1 つのコマンドで環境変数をファイルに書き出します。値が会話の記録に残ることはありません。printf '%s=%s\n' "$KEY_ENV_VAR" "$(printenv "$KEY_ENV_VAR")" > "$REPO/.saws-migrate/.source-provider-env" && chmod 600 "$REPO/.saws-migrate/.source-provider-env"次に、以下の形式チェックを実行し、
sourceBaselineAvailable = true、sourceKeyRef = "$REPO/.saws-migrate/.source-provider-env"を設定します。 -
自分でファイルに書き込む → ユーザー自身のターミナルで実行するコマンドを提示します(エージェント経由では実行しません。Claude Code では
!プレフィックスを付けるとセッション内で実行されます)。read -rsはキーをエコーせずに読み取ります。read -rs k && printf '%s=%s\n' "<KEY_ENV_VAR>" "$k" > "<REPO>/.saws-migrate/.source-provider-env" && chmod 600 "<REPO>/.saws-migrate/.source-provider-env" && unset k提示する際は、環境変数名とリポジトリパスを実際の値に置き換えてください(これらは秘密情報ではありません)。次に、以下の形式チェックを実行し、上記と同じフラグを設定します。
-
スキップ →
sourceBaselineAvailable = false、sourceKeyRef = ""。
どの方法でファイルに書き込んだ場合も、形式を検証してください(キーは出力されません。NAME= のプレフィックスなしで値が書き込まれた場合に検出できます。この場合、ベースラインパーサーはそのキーを黙って見落とします)。
grep -qE '^(OPENAI|ANTHROPIC|GEMINI)_API_KEY=.+' "$REPO/.saws-migrate/.source-provider-env" && echo KEY_FORMAT_OK || echo KEY_FORMAT_BAD
KEY_FORMAT_BAD の場合は、ファイルを書き込んだ方法と同じ方法で、内容を表示せずにファイルを書き直してもらいます。
(.saws-migrate/ は上記の最初のコマンドですでに Git の追跡対象から除外されています。リライターも、二重の対策としてコミット前にこの設定を再確認します。)
重要: ファイルがキーの受け渡し手段です。後続の手順にキーを渡すために export に頼らないでください。ある Bash 呼び出しで設定したシェルの状態は、別の呼び出しやワークフローのサブエージェントには引き継がれません。確実に参照できるのはプロファイルでエクスポートされた変数(上記の ENV_KEY_PRESENT の方法)のみですが、その場合もベースラインランナー用にファイルへ書き出す必要があります。
B4 — Bedrock プリフライト
uv run --project $SCRIPTS python $SCRIPTS/preflight_bedrock.py --region $REGION --models <comma-separated $TARGET_MODELS> --dataset-size 200
(--dataset-size 200 はゴールデンデータセットの上限と一致するため、クォータ警告は最悪ケースを反映します。B2 でデフォルト以外のプロファイルを選択した場合は、先頭に AWS_PROFILE=$AWS_PROFILE_CHOICE を付けてください。)
JSON 出力を解析します。失敗時は、TOP LEVEL に reason/detail(最初に失敗したモデルから取り出されたもの)と failing_models(失敗したすべての ID)が含まれます。モデルごとの判定は models[] にあります。
ok == false+reason: credentials→ detail を表示し(認証情報の設定/更新)、停止します。ユーザーは修正後に再実行します。ok == false+reason: model_access→ Bedrock コンソールでモデルアクセスが有効になっていません(IAM の問題ではありません)。失敗したモデルについて、ユーザーにコンソールの Model access ページを案内し、停止します。有効化後に B4 を再実行します。ok == false+reason: authz→ IAM が推論を拒否しています。Converse/InvokeModel ターゲットの場合は付与すべきアクションはbedrock:InvokeModelです。mantle 専用のopenai.gpt-5*ターゲットの場合はbedrock-mantle:*のセットです(B4a を参照)。detailにどちらかが示されます。付与すべきアクションをユーザーに伝え、停止します。ok == false+reason: mantle_deps_missing→ 固定されたスクリプト環境にopenai/aws-bedrock-token-generatorがないため、mantle 専用ターゲットをまったくプローブできませんでした。これは環境の障害であり、Bedrock の判定ではありません。ユーザーに再同期(uv sync --project $SCRIPTS)を伝え、停止します。続行しないでください — アクセスは検証されていません。ok == false+reason: model_unavailable→$HELPERS/resolve-bedrock-model-id/resolve-bedrock-model-id.mdにあるresolve-bedrock-model-idリファレンスを読み、failing_modelsの各 ID + リージョンでその手順に従います。候補を提示して AskUserQuestion を実行します:「<candidate>を使用する(クロスリージョン推論プロファイル)」/「別のモデル ID を貼り付ける」/「中止する」。選択されたら、$TARGET_MODELSの ID を置き換えて B4 を再実行します。ok == false+ その他のreason→detailを表示して停止します。ok == true→ 続行します。quota_warningがあれば提示し、またreasonがembedding_unprobedであるモデル(プリフライトでプローブできない埋め込みファミリー — ユーザーにコンソールでモデルアクセスを確認するよう促してください)があれば提示します。
フェーズ C — 実行
フェーズ C は、Agent ツール(サブエージェントタイプ aws-startup-advisor:llm2bedrock-code-analyzer、aws-startup-advisor:llm2bedrock-log-ingestor、aws-startup-advisor:llm2bedrock-prompt-evaluator、aws-startup-advisor:llm2bedrock-code-rewriter、aws-startup-advisor:llm2bedrock-report-generator)を介して、5 つのプラグインエージェントを順番にディスパッチします。各エージェントは結果を $PHASE_DIR = $REPO/.saws-migrate/phase-results/ 配下のファイルに書き込みます。次に進む前に、同梱のバリデーターで各ファイルを検証します。ワークフローランタイムはありません — ファイルがそのまま状態です。
バリデーター(各ステップで使用)
uv run --project $SCRIPTS python $SCRIPTS/validate_result.py --schema <analysis|ingestion|eval|rewrite|delta-decisions> <file>
- 終了コード 0 +
RESULT=valid CONTROL=ok→ フェーズ完了。続行します。 - 終了コード 0 +
CONTROL=blocked REASON=<r>→ ブロックフロー(下記)。 - 終了コード 0 +
CONTROL=partial COMPLETED=<n> TOTAL=<m>→ 部分フロー(eval のみ)。 - 終了コード 1(
RESULT=invalid+ エラー行)または終了コード 2(ファイル欠落)→ ステートレス修正リトライ: 同じタイプの新しいエージェントをディスパッチします。そのプロンプトは、元のコンテキストブロック + ファイルパス + バリデーターのエラー出力そのまま + 指示「<path>にある出力ファイルのみを、検証に通るよう修正してください。必須フィールドが本当に欠けている場合を除き、フェーズの作業をやり直さないでください」です。フェーズごとに最大 2 回のリトライとし、その後は停止してエラーを表示します。
コンテキストブロック(各ディスパッチで生成)
エージェントはラベルを解析するため、この正確な行形式で作成します。空の場合は、任意の行を省略してください。
Repository: <$REPO>
AWS region: <$REGION>
AWS profile (pass as --profile / AWS_PROFILE= inline on every aws/boto3 invocation): <$AWS_PROFILE_CHOICE — omit line if default>
Target Bedrock model(s): <comma-joined $TARGET_MODELS, with any resolved overrides already applied>
Migration plan dir: <$MIGRATION_DIR>
Resolved target model id: <override for the primary chat model — omit if none>
Scripts directory (pinned uv toolchain): <$SCRIPTS>
Report date suffix: <saved suffix from run-context — C5/C6 dispatches only>
Source baseline available: <true|false>
Source provider env file: <path — omit if none>
User-supplied log files: <comma-joined — omit if none>
Golden dataset cap (max cases the ingestor may emit): 200
Phase results directory: <$PHASE_DIR>
Prior phase results (Read these files): <paths of already-validated phase JSONs>
Confirmed behavior-delta decisions file (Read it): <$PHASE_DIR/delta-decisions.json — C5 only>
<helper-reference lines — inject ONLY the ones this agent needs, per the table below>
前フェーズの結果は FILE PATHS として渡します。JSON をプロンプトに直接埋め込まないでください。
ヘルパー参照(以前のヘルパースキル。現在は $HELPERS 配下)。 エージェントはスキル名で読み込むのではなく、注入した絶対パスにあるヘルパー参照を読み込みます。各ディスパッチでは、エージェントが使用するヘルパー行(# 4 セクションに記載)だけを追加してください。
| エージェント(ディスパッチ) | 追加するヘルパー参照行 |
|---|---|
| C1 llm2bedrock-code-analyzer | behavior-delta-detection reference: $HELPERS/behavior-delta-detection/behavior-delta-detection.mdresolve-bedrock-model-id reference: $HELPERS/resolve-bedrock-model-id/resolve-bedrock-model-id.md |
| C5 llm2bedrock-code-rewriter | bedrock-known-fixes reference: $HELPERS/bedrock-known-fixes/bedrock-known-fixes.mdbehavior-delta-detection reference: $HELPERS/behavior-delta-detection/behavior-delta-detection.mddependency-conflict-resolution reference: $HELPERS/dependency-conflict-resolution/dependency-conflict-resolution.md |
| C3 llm2bedrock-prompt-evaluator | bedrock-known-fixes reference: $HELPERS/bedrock-known-fixes/bedrock-known-fixes.mdresolve-bedrock-model-id reference: $HELPERS/resolve-bedrock-model-id/resolve-bedrock-model-id.mdrun-source-model-baseline reference: $HELPERS/run-source-model-baseline/run-source-model-baseline.md |
| C2 llm2bedrock-log-ingestor、C6 llm2bedrock-report-generator | (なし — これらのエージェントはヘルパーを読み込みません) |
$HELPERS は、<SKILL_BASE> を使って絶対パスに展開します。${CLAUDE_PLUGIN_ROOT} が空のサブエージェントでも解決可能な絶対パスを受け取れるようにしてください。
C0 — 実行コンテキストゲート(再開時の安全性)
Eval フェーズでは、ゴールデンケースごとに Bedrock を有料で 1 回呼び出します(ソースキーがある場合は、ケースごとにソースプロバイダーも有料で 1 回呼び出します)。ディスパッチを行う前に、評価ではユーザー負担で Bedrock が呼び出されることと、対象が最大 200 ケースであることをユーザーに伝えてください。
mkdir -p $PHASE_DIR。$PHASE_DIR/current-context.jsonを、次のフィールドだけで作成します(ハッシュの生成にはshasum -a 256を使用します。キーのハッシュはフィンガープリントであり、キーの値は決して保存しないでください)。
{
"repo_root": "<cd $REPO && pwd -P>",
"migration_dir": "<$MIGRATION_DIR>",
"region": "<$REGION>",
"aws_profile": "<$AWS_PROFILE_CHOICE or \"\">",
"aws_account": "<Account from B2>",
"repo_head_sha": "<git -C $REPO rev-parse HEAD>",
"repo_branch": "<git -C $REPO rev-parse --abbrev-ref HEAD>",
"repo_dirty_sha256": "<sha256 of: git status --porcelain + git diff + git diff --cached, EACH with pathspecs -- . ':(exclude).saws-migrate' ':(exclude).migration' ':(exclude)MIGRATION_REPORT_*.md'; \"\" when all three are empty>",
"target_models": [{"source_model": "...", "aws_model_id": "...", "use_case": "..."}],
"resolved_model_overrides": {},
"source_provider": "<from B1>",
"source_baseline_available": <true|false from B3>,
"source_key_sha256": "<sha256 of .source-provider-env contents, \"\" when absent>",
"log_files": [{"path": "...", "sha256": "..."}],
"max_golden_cases": 200,
"assess_design_sha256": "<sha256 of $MIGRATION_DIR/aws-design-ai.json>",
"report_date_suffix": "<date +%Y-%m-%d>",
"schema_version": 1,
"plugin_version": "<version from <plugin>/.claude-plugin/plugin.json>"
}
-
ステージ 0(C5 後の正規化)。
$PHASE_DIR/rewrite.jsonが存在し、ペイロードとして検証に合格する(CONTROL=ok)場合、実行中のrepo_*の値は使用しないでください。次の 3 つの整合性チェックを実行します。 (1)rewrite.baseline_parent_shaが保存済みのrepo_head_shaと一致すること。(2)git rev-parse <rewrite.branch_name>がrewrite.branch_tip_shaと一致すること。(3)git status --porcelain(アーティファクトの除外を適用)が空であること。すべて合格した場合 → 保存済みのrepo_*の値を現在のコンテキストにそのままコピーし、ステップ 3 に進みます。チェック 2 が失敗した場合(先端が移動)→ 停止して AskUserQuestion を提示します:「コミットを保持する(混在した作成者に関する注記を付けてレポートのみ再生成)」/「ブランチをリライターの先端にリセットし、C6 から再生成」/「中止」。チェック 3 が失敗した場合(作業ツリーが汚れている)→ 停止し、コミット/スタッシュ(その後再チェック)するか、編集を破棄するよう尋ねます。チェック 1 が失敗した場合 → ステップ 3 でrepo_*全体の不一致として扱います。 -
$PHASE_DIR/run-context.jsonが存在する場合、次を比較します。
uv run --project $SCRIPTS python $SCRIPTS/validate_result.py --check-run-context $PHASE_DIR/run-context.json --current $PHASE_DIR/current-context.json
RUN_CONTEXT=match→ 再開します。C1→C2→C3→(C4:delta-decisions.json)→C5→(C6:レポートファイル)の順に進めます。ファイルがCONTROL=okで検証された場合に限り、そのフェーズを完了とみなします(C6 は、rewrite.json がペイロードとして有効であり、MIGRATION_REPORT_<saved suffix>.mdが存在する場合に限ります)。最初の欠落/無効/制御状態のファイルで処理を停止します。ブロック中/部分的なファイルは、以下の各フローに従って処理し、完了として扱うことは決してありません。ユーザーに「完了済みのフェーズ X..Y をスキップして、Z から再開」することを提案します。説明のつかない中断箇所より後にあるファイルは、中断箇所と一緒にアーカイブします。RUN_CONTEXT=mismatch→ 対象を限定して無効化します。各 MISMATCH 行を次の表に照らし合わせ、該当するユニットを$REPO/.saws-migrate/phase-results-archive/<saved suffix>-$(date +%H%M%S)/(phase-results/ と並列のディレクトリであり、その中には決して作成しない)にアーカイブし、その後ただちに、現在のcurrent-context.jsonでrun-context.jsonを上書きします(REPORT 自体を無効化する場合を除き、保存済みのreport_date_suffixを引き継ぎます)。次に、無効化されたフェーズを順に再実行します。異なっていたフィールドと、再実行する内容をユーザーに伝えます。
| 不一致のフィールド | アーカイブ(ユニット) | 保持 |
|---|---|---|
| repo_root、migration_dir、region、aws_profile、aws_account、source_provider、assess_design_sha256、schema_version、plugin_version | すべて | — |
| repo_head_sha / repo_branch / repo_dirty_sha256 | すべて | — |
| target_models / resolved_model_overrides | ANALYSIS、EVAL、REWRITE、REPORT | INGESTION |
| log_files / max_golden_cases | すべて | — |
| source_key_sha256 / source_baseline_available | ANALYSIS、EVAL、REWRITE、REPORT | INGESTION |
ユニット:ANALYSIS = analysis.json · INGESTION = ingestion.json + .saws-migrate/golden-dataset/
· EVAL = eval.json + .saws-migrate/eval-results/(cost_compare.py を除く) · REWRITE =
rewrite.json + delta-decisions.json · REPORT = MIGRATION_REPORT_<saved suffix>.md。
C5 後に C1~C3 を再実行するには、移行前のツリーが必要です。 rewrite.json がペイロードとして有効で、表によって ANALYSIS/INGESTION/EVAL が無効化される場合、古い移行ブランチを破棄することをユーザーに確認してから(先端が移動している場合は、まず保持またはリセットのフローを実行)、git checkout <saved repo_branch> を実行し、古いブランチと saws-migrate-baseline タグを削除して、C1 から再実行します。ユーザーが同意しない場合は停止します。書き換えを含むツリーを再分析すると、意味のない結果になるためです。
- 保存済みの実行コンテキストがない場合 → 新規実行:current-context.json を run-context.json として書き込み、C1 をディスパッチします。
C1 — アナライザー · C2 — インジェスター · C3 — 評価者
各フェーズを順番に実行します。コンテキストブロック(すべての前フェーズのファイルパスを記載)とともにエージェントをディスパッチし、その後、出力ファイルを検証します。
| ステップ | agentType | 出力ファイル | スキーマ |
|---|---|---|---|
| C1 | aws-startup-advisor:llm2bedrock-code-analyzer | $PHASE_DIR/analysis.json | analysis |
| C2 | aws-startup-advisor:llm2bedrock-log-ingestor | $PHASE_DIR/ingestion.json | ingestion |
| C3 | aws-startup-advisor:llm2bedrock-prompt-evaluator | $PHASE_DIR/eval.json | eval |
ブロック時のフロー(CONTROL=blocked):REASON に応じてユーザーと解決します —
model_access→ ユーザーが Bedrock コンソールでモデルを有効にします(フィンガープリントに関わる変更はありません。ブロックされたフェーズのみ再ディスパッチします)。model_unresolvable→ ユーザーが ID を選択または貼り付けます →resolved_model_overridesに記録し、Target 行に反映します。source_key_auth→ ユーザーが新しいキーを提供します(B3 を再実行)、またはベースラインを利用不可に設定します。authz→ IAM によって推論が拒否されています。detailに、許可するアクションのセットが示されています。Converse ターゲットの場合はbedrock:InvokeModel*、mantle 専用のopenai.gpt-5*ターゲットの場合はbedrock-mantle:*アクション(CreateInference、CallWithBearerToken)です。ユーザーが IAM を修正します。フィンガープリントに関わる変更はないため、ブロックされたフェーズのみ再ディスパッチします。これをmodel_accessに振り分けないでください。コンソールの Model access ページは IAM による拒否の修正には適しておらず、その逆も同様です。mantle_deps_missing→ 固定されたスクリプト環境にopenai/aws-bedrock-token-generatorがないため、mantle ターゲットをまったくプローブできませんでした。ユーザーが再同期します(uv sync --project $SCRIPTS)。ブロックされたフェーズのみ再ディスパッチします。アクセスは一度も検証されていないため、以前の合格を有効なまま扱わないでください。assess_output_missing→ Phase A を再実行し、その後 Phase C を C0 から再開します。
解決後は必ず、C0 の手順を再実行します(current-context を再構築し、無効化テーブルを適用し、run-context を上書きします)。その後、最も早い無効化フェーズから再ディスパッチします。実行の再開位置を決めるのはブロックされた箇所ではなく、テーブルです。
部分実行のフロー(評価のみ、CONTROL=partial):AskUserQuestion —
- 残りのケースを続行 → 次の追加コンテキスト行を付けて評価者を再ディスパッチします:
Resume: raw_results.jsonl already contains completed cases — evaluate only prompts whose ids are not present in it, then re-score and overwrite eval.json - 部分的な合格率で続行 → 次の指示を付けて評価者を再ディスパッチします:
Finalize partial: do NOT call Bedrock again — score the cases already in raw_results.jsonl and emit the FULL eval payload over only those cases, with total_cases = the number scored and a notes prefix line 'partial_coverage: <completed>/<total> cases (throttled)'。その後、C4 を通常どおり実行します。 - 中止 → 停止します。ファイルはディスク上に残り、後で C0 から再開できます。
C4 — サイドバー(2 つのゲート)+決定の永続化
ゲート(a)— 品質の続行/中止。 $PHASE_DIR/eval.json を読み込みます。しきい値は
pass rate >= 0.9 AND source_baseline_quality != 'poor' です(notes に
no_golden_cases: true がある場合、品質シグナルはありません。必ず確認してください)。しきい値以上の場合は、何も表示せずに続行します。
しきい値未満の場合は、AskUserQuestion を表示します。
- そのまま続行 → ゲート(b)
- ターゲットモデルを変更 →
resolved_model_overridesに記録し、C0 を再実行します(このテーブルによって ANALYSIS/EVAL が無効になり、C1 から実行が再開されます)。再試行の上限:2 回。 - 中止 → 停止し、コードには触れません。
ゲート(a.5)— 書き換え戦略(移行計画に基づく)。 $MIGRATION_DIR/aws-design-ai.json →
ai_architecture.code_migration.migration_path から migration_path を読み込みます。
値が "mantle"("mantle"、"mantle_openai_responses")で始まる場合は、
rewrite_strategy = "mantle" に設定します。それ以外(値が "converse"、"gpt-oss"、またはフィールドがない場合)は、rewrite_strategy = "converse" に設定します。
ユーザーへの確認は不要です。この決定は Assess/Design フェーズですでに行われています。
完全一致ではなく、プレフィックスで判定してください。Design は同一モデルの OpenAI 移行の場合、より具体的な
"mantle_openai_responses" を書き込みます。"mantle" との完全一致で判定すると、これらの実行は
気付かれないまま Converse の経路に進み、動作している同一モデルのコードが、Converse のインターフェイスを持たないモデルに対する boto3 Converse クライアントへと書き換えられてしまいます。
ゲート(b)— 動作差分の解決。 analysis.behavior_deltas[] のうち
user_visible == true のものごとに、behavior-delta-detection リファレンス($HELPERS/behavior-delta-detection/behavior-delta-detection.md と、その references/ ディレクトリ内の source_provider サブリファレンスを読み込みます)にある選択肢を使って AskUserQuestion を表示します。
永続化: 決定の配列(各エントリは {delta_type, location, resolution_chosen, source}。ユーザーに見える差分がない場合は [])を $PHASE_DIR/delta-decisions.json
に書き込み、検証します(--schema delta-decisions)。C5 より前にこのファイルが存在している必要があります。これにより、C5 の再試行やクラッシュ後の再開を単独で行えます。
C5 — リライター · C6 — レポート
| ステップ | agentType | 出力 | スキーマ |
|---|---|---|---|
| C5 | aws-startup-advisor:llm2bedrock-code-rewriter | $PHASE_DIR/rewrite.json | rewrite |
| C6 | aws-startup-advisor:llm2bedrock-report-generator | リポジトリのルートにある MIGRATION_REPORT_<saved suffix>.md | (なし — 完了確認はファイルの存在で行います) |
C5 のコンテキストブロックには、Confirmed behavior-delta decisions file の行と
Report date suffix の行が含まれます(今日の日付ではなく、再開時は run-context の値を使用します)。C6 のコンテキストブロックには、4 つすべてのフェーズ結果ファイルのパスが記載されます。
rewrite_strategy == "mantle" の場合、C5 のコンテキストブロックには、さらに以下も含まれます。
Rewrite strategy: mantle(Converse の場合、この行は完全に省略します。行がないことがデフォルトの Converse パスを示します)Mantle model map: <source-model> -> <bedrock-model-id>— プランのai_architecture.bedrock_models[]エントリーを参照します(各source_model→aws_model_idのペア)。- マッピングされた
aws_model_idのいずれかが独自 GPT モデル(openai.gpt-5*)の場合、Mantle surface: responsesとMantle base path: /openai/v1を指定します。これらは Responses API を介して/openai/v1パスでのみ提供されます。他の Mantle モデルが使用するv1パスとは異なるため、リライターはこれらのモデルに対して/v1ベース URL や Chat Completions 呼び出しを出力してはいけません。 詳細はgcp-to-aws/references/shared/openai-on-bedrock.mdを参照してください。 bedrock_models[].model_changeがfalseの場合は、Same model: trueを指定します。これは、リライターにモデルパラメーターを変更せず、エンドポイント、認証情報、モデル ID、および(ソースで Chat Completions が使用されていた場合は)API サーフェスの再構成に変更を限定するよう指示します。
C7 — サマリーの表示
uv run --project $SCRIPTS python $SCRIPTS/render_report.py --phase-results $PHASE_DIR --repo $REPO --date-suffix <saved suffix>
サマリーを出力します。rewrite.branch_name(通常は bedrock-migration ですが、すでにそのブランチがある場合は bedrock-migration-2 のように衝突を示すサフィックスが付きます)とレポートファイルをユーザーに案内します。元に戻す方法も説明してください。必ず rewrite.branch_name の実際のブランチ名に置き換え、ハードコードされた名前は使わないでください(ブランチ名が衝突した場合、bedrock-migration はユーザーがすでに所有しているブランチです。削除するとユーザーの作業が失われます)。
破棄するには、
git checkout <your original branch>、git branch -D <rewrite.branch_name>、git tag -d saws-migrate-baseline、およびrm -rf .saws-migrate .migrationを実行すると、API キーファイルを含むすべての移行アーティファクトが削除されます。
インラインモード(Agent/サブエージェントのディスパッチツールがないプラットフォーム向け)
このプラットフォームにサブエージェントのディスパッチツールがない場合は、各フェーズの間に必ず停止しながら、フェーズをインラインで1つずつ実行します。
- エージェント定義(
<plugin>/agents/<name>.md)を正確に1つだけReadします。一度に複数のフェーズの定義をコンテキストに読み込んではいけません。 - 最初から最後まで手順に従い、同じフェーズ結果ファイルを書き込み、検証します。
- 停止します。フェーズの結果(バリデーターの CONTROL 行と1行のサマリー)を報告し、次のフェーズの定義を読み込む前にユーザーに確認を求めます。このサイドバーは必須です。コンテキストの負荷を軽減し、ユーザーが新しいセッションで続行しても、フェーズ結果ファイルによって内容が失われないようにします。
インラインモードはサブエージェントのディスパッチより時間がかかり、コンテキストへの負荷も大きいこと、またリライターフェーズではこのセッション内でブランチ、コミット、ワークツリーなどの git 操作を直接実行することを、事前にユーザーに伝えてください。
失敗時の処理
- エージェントのディスパッチが失敗する(ツールエラー、ターミナルの失敗)→ フェーズファイルがない → バリデーターが終了コード 2 を返す → ステートレスな修正・再試行の経路(修正するファイルがないため、フェーズを再実行します)。再試行は最大 2 回までとし、それを超えて自動再試行しないでください。
- ユーザーがいずれかのゲートで中止する → SOURCE CODE が変更されていないことを確認します(それ以前に中止した場合、C5 は開始されていません)。
.migration/と.saws-migrate/のアーティファクトは存在することに注意してください。ユーザーが削除したい場合は、C7 の取り消しコマンドを提示します。 - 評価スキルが失敗する → エラーを表示して停止します。ユーザーは
/aws-startup-advisor:llm-to-bedrockを再実行できます。
コンテキストに応じたオファー(最終ステップ)
完了する前に: 以下の コンテキストに応じたオファー(最終ステップ) を実行するまでは、回答は完了していません。
これは、最終的な推奨を行うたびに必須となる締めくくりのステップです。回答を完了とする前に実施してください。このオファーの確認はその場で行い、別のスキルの読み込みに依存しないでください。推奨はまず内容の妥当性に基づいて決定します。このステップによって推奨を変更、再ランク付け、再検討することはありません。オファーを調べるのは、助言が確定した後だけです。
../knowledge-base-for-startups/references/offers.mdを読みます。これはオファーのインデックス(オファー・概要・キーワード)で、オファーごとに 1 行あります。- 創業者がこのセッションで実際に示した内容に照らして、関連性を判断します。次のいずれか 1 つに該当する場合のみ、オファーを提示します。製品名の一致(特定のパートナー製品を名前で推奨し、その製品の行がある)、または直接的な意図・コンポーネントの一致(オファーのキーワードが、具体的なワークロード、最終的な推奨に含まれるコンポーネント、または創業者が挙げたニーズに直接役立つ)。基準は高く保ってください。一致が弱い場合や、明示されていないニーズを推測する必要がある場合は、何も追加しません。
- オファーが基準を満たした場合に限り、その詳細ファイル
../knowledge-base-for-startups/references/offers/<slug>.mdだけを開き、価値を伝え、同ファイルの条件を正確に要約した、控えめで表示を消せるイタリック体の行を1 行だけ追加します(条件を省略せず、捏造しないでください)。その行には、正規のsource_urlにsourceアトリビューションパラメーターを付けた引き換えリンクを含めます。URL にクエリ文字列がある場合は&source=...、ない場合は?source=ide-startupAdvisor-<host>を付けます。実行環境に応じて<host>を設定します(Claude Code →claude、AWS Startup Advisor IDE extension / VS Code →vscode、Cursor →cursor、Kiro →kiro、Codex →codex)。判別できない場合は汎用のide-startupAdvisorを使用します。クエリパラメーターのみを追加し、リンク先は変更しないでください。提示するオファーは 1 件または 0 件とし、一覧にはしません。
標準行:
***<Offer>** has an exclusive offer via AWS Activate — <value>, <eligibility>. [Redeem →](<source_url>?source=ide-startupAdvisor-<host>)*
上限と制御:回答ごとに最大 1 件、通常は 0 件とします。5 メッセージにつき 1 件まで、セッション全体で 2 件までです。同じオファーはセッション中に 1 回までとし、すでに提示、利用、または非表示にされたオファーは提示しません。創業者がオファーをミュートしている場合、このステップ全体を省略します。5 メッセージごと、セッションごと、および提示済みかどうかに関する上限は、セッション状態に依存する制限です。過去のオファーがない新しいセッションでは適用されないため、セッション履歴を確認できないという理由だけで、基準を満たすオファーを提示しないことは避けてください。詳しいルールは ../contextual-offers-for-startups/SKILL.md を参照してください。ただし確認はその場で行い、このスキルの読み込みに依存してはなりません。