mcpField
G
gtm-workflow

gtm-workflow

github.com/eliasstravikマーケティング・グロース22335 回インストール2 週間前に更新
リポジトリ

gtm-workflow について

gtm-workflow は、GTM ワークフローを作成、変更、実行、デプロイするユーザー向けのエージェントスキルです。ローカルとデプロイ済みのワークスペースで、ワークフロー、実行履歴、UI 操作を扱います。

主な機能

  1. 01ワークフローの作成、変更、削除
  2. 02実行、テスト、スケジュール、デプロイ
  3. 03グループ、実行履歴、図の管理
  4. 04ワークスペース設定とマイグレーション

活用シーン

  1. 01テンプレートから GTM ワークフローを作成
  2. 02データを保持しながら既存フローを更新
  3. 03ワークフローを実行、またはホスト環境へデプロイ
  4. 04実行履歴を確認し、ワークフロー UI を開く

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/eliasstravik/gtm-skills --skill gtm-workflow

インストール後、Claude Code で/gtm-workflowを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

recipes/
README.md
recipes/enrich-network/
acceptance.md
interactions.md
README.md
recipe.md
references/
connections.md
deploy.md
entry-links.md
imports.md
interactions.md
linked-data.md
local-and-production.md
local.md
patterns.md
profile-field-inventory.json
profile-fields.md
reliability.md
shared-profiles.md
viewer.md
scripts/
doctor.mjs
hosted.mjs
root-files.mjs
scaffold-manifest.mjs
setup.mjs
share-firewall.mjs
template.mjs
upgrade-package.mjs

詳細

GTM ワークフロー

トリガー

保存済みワークフローに関するリクエスト(作成、変更、実行、スケジュール設定、デプロイ、アップグレード、確認、UI を開く、グループ化、削除)、またはそのテーブル、実行履歴、図、グループに関するリクエストを受けた場合は、このスキルを適用します。

ワークフローを作成または変更する場合は、リクエストに合うものがないかレシピ(例:ネットワークエンリッチメント)を確認し、それに従ってください。ライフサイクルの管理は引き続きこのスキルが担当します。変更のないワークフローを通常どおり実行する場合、レシピは不要です。

ユーザーのリクエスト全体が /gtm-workflow または /gtm-workflows のみで、アクションやほかの語句が含まれない場合に限り、インテントメニューを表示します。**ワークフローの操作を選択してください。**と尋ね、次の3つの選択肢を提示して、返答を待ちます。GTM Workflows を開く、ワークフローを作成する、ワークフローを管理する。管理を選択した場合は、対象のワークフローとアクション(変更、実行/テスト、スケジュール設定/デプロイ、グループ化、アップグレード/修復、削除)を尋ねます。単独で呼び出された場合は、作成、実行、デプロイを行いません。

GTM Workflows を開くは、明示的な Open リクエストです。エントリーリンクを使って確認済みのビューアー URL を解決し、すぐに返してください。インテントメニューを表示したり、もう一度 Open を選ぶようユーザーに尋ねたりしないでください。このスキルの読み込みによって、明示的なリクエストが単独の呼び出しに変わることはありません。ほかの明示的なアクションも、それぞれの手順に直接進んでください。Open の際にワークスペースが見つからない場合は、ワークスペースのセットアップについて説明してください。ワークスペースにワークフローがない場合は、空の一覧を表示してください。

スコープ

このスキルが管理するのは <workspace>/workflows/ です。これは Nitro 上で動作する Vercel Workflow ランタイムで、初回使用時にテンプレートの templates/ からコピーされます。対象には、ワークフローファイル、db/tables/、マイグレーション、vercel.json、.env、ローカルデータベース、実行履歴、図のページ、デプロイ済みコピーが含まれます。デフォルトでは、実行はこのワークスペース固有の data/pg 内にある Postgres に対してローカルで行われます。ユーザーが要求した場合、またはホストがローカル実行履歴はないと述べた場合は、デプロイ済みコピーを対象とします。ホスト上の実行結果は、デプロイ済みコピーのクエリルートを通じて読み取ります。キーは、ローカルでは workflows/.env.local に、デプロイ時はプロジェクトの Production 変数に保存され、どちらもビューアーの Keys ページ(Connections タブ)から編集します。セットアップ、キーの検出、キーの変更については、Keysを参照してください。workflows/ 以外の残りのワークスペースファイルは、ほかの gtm スキルが管理します。

ワークフローテンプレートはこのスキル内には含まれていません。このスキルのフォルダーから node scripts/template.mjs を実行すると、このスキルのリリース用テンプレートを gtm-skills リポジトリからタグ v<metadata.version> で一度だけ取得します(ブランチは使用しません。まず git で取得するため、exe.dev VM では github.localhost プロキシが適用され、その後にリリース tarball を使います)。テンプレートは ~/.cache/gtm-skills/ にキャッシュされ、コピー先の workflows/ に入るランタイムフォルダーを templates とし、ワークスペースのルートファイルを含むフォルダーを root とする JSON を出力します。セットアップ、Doctor、upgrade-package.mjs はそれぞれ内部でこの処理を呼び出します。このスキルまたはその参照先で templates/ または root/ と記されている場合は、この2つのフォルダーを指します。取得に失敗した場合(終了コード 1、template_fetch_failed)は、その理由を報告してください。ワークスペース内のそれ以外の内容は変更されません。

入力

リクエスト、契約に従って見つけたワークスペース、ワークフローがスラッグで参照する ICP とペルソナ、コマンド、キー、確認済みの事実については references/local.md、ホスティングについては references/deploy.md。

ロール

ユーザーのリクエストは、設定された行数上限およびコスト上限の範囲内で、通常のコード変更と実際の実行を承認するものです。見積もりを伝えて、そのまま進めてください。確認が必要なのは、共通の対話ルールに基づく破壊的な操作のみです。ワークフロープロジェクトは、共通セットアップの --deploy(deploy.md)を通じて、または任意の gtm-agent セットアップの最終ステップとして直接実行して公開します。ユーザーはワークスペースごとに .env で AI バックエンドを一度選択し、エージェントが作成、実行、報告を行います。デプロイはプッシュ操作です。

手順

エンリッチした人物や企業を永続化する場合は、ストレージ、ID、鮮度、有料の試行、スコープ付きの Data ビューについて、共有プロフィールに従ってください。複数フェーズのエンリッチメントでは、2フェーズのワーカーと共通の予算により、以下の汎用的な自己ファンアウトパターンを置き換えます。プロフィールのテーブルはスキーマ gtm 内のランタイムテーブルです。scripts/migrate.mjs がほかのすべてとともにこれらを移行し、アップグレード後も保持されます。

会話で最初に使用する gtm スキルは、更新の説明どおり、新しいリリースがあるかどうかを1回確認します。やり取りに記載された6つのルールに従って会話し、対話例を再現してください。ワークフローのスラッグはコントラクトのスラッグ規則に従います。表示名には、ドキュメントコメントの1行目を使用します。

作業対応内容
作成個人用コンピューターで初めて使う場合は、Keys に記載された共通のローカルセットアップを実行します。空のレジストリを作成し、実行はせずにローカルデータベースを準備します。ホストされた環境での作成では、すでに設定済みのランタイムを使用します。npm run dev を開始します(ローカルで実行するコマンドはこれだけです。ビューアー、Keys ページ、実行機能が起動します。開いても何も実行されません)。データの行がどこから来るかを尋ねます。ワークフローが人に処理を求める箇所(ステージでの承認、または notify 呼び出し)に達したら、投稿先の Slack チャンネルを一度だけ尋ねます。チャンネル ID(C0…。チャンネルの About タブの下部に表示)か「ここ」のどちらかです。「ここ」は、エージェントがこの会話のチャンネル ID を把握している場合にそのチャンネルを意味します。回答はワークフローファイルの先頭にある NOTIFY 定数になり、すべてのステージと notify 呼び出しに notify として渡されます。プロジェクト変数にはしません。ワークフローごとにバックエンドを尋ねることはありません。エージェントステージは実行時に .env から GTM_AGENT_BACKEND を読み取ります(個人用コンピューターで作者のサブスクリプションを使う場合は claude または codex、AI Gateway を使う場合は未設定)。そのため、同じファイルをローカルではサブスクリプション経由、ホスト環境では Gateway 経由で実行できます。個人用コンピューターでひな形を作る際、claude または codex が PATH 上にあり、Gateway キーがない場合は、一度だけ設定してその旨を伝えます。それ以外の場合は未設定のままにします。viewer を使って、viewer.businessGraph と viewer.description(約 280 文字、最大 500 文字)をリテラルで記述し、新しいコードと照らし合わせてラベルと分岐を確認します。example-scores.ts を基に workflows/<slug>.ts を作成します。エージェントステージがある場合は example-research.ts を基に作成し、そのテーブルを db/tables/<name>.ts に作成します。両方を workflows/index.ts と db/tables/index.ts に登録し、workflows/groups.ts のグループにスラッグを追加します(Group を参照。計画にはグループ名とその理由を記載し、計画のほかの部分と併せて承認を得ます)(サンプルのワークフローとテーブルは残します。同じ generate でテーブルを削除して別のテーブルを追加すると、ジェネレーターがリネームについて質問しますが、ホスト環境では回答できません)。npm run db:generate -- --name <name> を実行し、新しいワークフローの ID を割り当てるために npm run viewer:register を一度実行します。ビルドして Diagram ページを開き、コミットし、作成した内容と Open GTM Workflows エントリを伝えて締めくくります。ローカル実行のないホストでは、ローカルホストへのリンクは絶対に提示しません。push 後、デプロイ済みコピーで GET /api/link/<slug> を 10 秒おきに最大 3 分間読み取り、返された commit に対して git merge-base --is-ancestor HEAD <commit> が成立するまで待ってから、検証済みの viewerUrl を提示します。これが成立する前に返信する場合はリンクを載せず、デプロイ中であることを伝えます。ユーザーから実行を依頼されたら、キーと上限を確認したうえで、追加の確認を求めずに依頼された範囲を実行し、見積もりを伝えます。ローカル実行のないホストで接続済みプロジェクトがない場合は、代わりに deploy.md に記載された接続手順を示して締めくくります。
更新ワークフローと、その viewer.businessGraph および viewer.description を一緒に変更します。新しいビジネス判断の分岐や担当者の詳細も反映します。viewer.id は保持し、node scripts/build-viewer.mjs でメタデータを検証します。export const criteria のコピーを readIcp/readPersona に移します(Criteria を参照)。列を追加した後、db:generate を実行します(実行中の npm run dev が反映します)。既存データは保持し、変更内容と Open GTM Workflows エントリを伝えて締めくくります。
実行対象:個人用コンピューターではデフォルトでローカル、ユーザーから依頼された場合、またはホストがローカル実行に対応していないと明示した場合はデプロイ済みコピーを使います。デプロイ済みコピーの実行には接続済みプロジェクトと、先に Deploy の準備状況チェックが必要です。実行前に、行数、行数 × 見積もりが両方の上限内か、ワークフローが使用するすべての接続が Connections に記載された対象環境の接続一覧にあるか、前回の実行以降にワークフローが新規作成または変更されたかを確認します。依頼された実行は、1 行でも複数行でも、権限確認や先にテストするかどうかの質問をせずに進めます。行数と見積もりコストを伝えてから、依頼された範囲を実行します。キーがない場合や上限を超えた場合は実行を中止し、阻害要因を伝えます。ルート経由で開始し、読み取りルートをポーリングし、結果を平易な言葉で伝えて締めくくります。完了、失敗、スキップ、コストを含めます。スレッドで前回リンクを提示して以降に変更がない限り、リンクは載せません。読み取りルートに保留中の承認が表示された場合は、ポーリングを停止し、1 通のメッセージで相手に確認します(ツール、その入力内容を平易な言葉で説明し、判明している場合は料金も伝えます)。その回答と理由を添えて承認ルートから決定し、ポーリングを再開します。stream が有効な実行は、実行中にストリームルートから状況を伝えてもかまいません。ホスト環境での実行後にローカルで実行する場合は、ホスト側のコピーがすでに処理した行を再度処理して費用が発生する可能性があると伝えます。
UI を開く「Open GTM Workflows UI」またはリンクを明示的に求められた場合は、entry links に従います。安定した ID で対象のワークフローを特定します。ID がない場合は一覧を開きます。準備状況を確認します。ローカルでは必要に応じて npm run dev を開始します。その Connections タブ(<viewer origin>/connections。キーの設定先として案内するアドレス)は、同じサーバー上の Keys ページです。UI を開いても、ワークフローの実行、マイグレーション、ホストにない環境のデプロイは行われません。利用できない場合は、具体的なセットアップ上の阻害要因を伝えます。明示的に求められた場合は、すでに提示済みでも必ずエントリを返します。
共有ホスト環境のみ:/api/viewer/service?v=3&workflow=<id>&op=grants を使って grants を読み取ります。明示的に保存する前に、選択されているタブと現在許可されているデータの概要を表示します。{views, policy, save} を指定して saveLink に POST します。policy は表示されたハッシュです。save: true は、範囲またはポリシーの変更を明示的に承認する指定です。変更なしでコピーする場合は、既存のリンクを再利用します。デフォルトは有効期限なしの Diagram です。アクティブな ID を指定して revokeGrant に POST すると無効になります。再有効化すると新しいシークレットが作成されます。返された URL をそのまま使用します。viewer を参照してください。
デプロイデプロイとは push のことです。一度限りの接続設定と準備状況チェックについては deploy.md に従います。push はすでに実行中の処理には影響せず、実行開始時のコードで最後まで処理されます。ホスト上のコピーは、ローカルの .env の設定にかかわらず、すべてのエージェントステージを Gateway 経由で実行します。
アップグレードまず、このスキルのフォルダーから node scripts/upgrade-package.mjs <workflows> を実行します(プレビューであり、何も書き込みません)。このスキルのテンプレートがワークスペースより古い場合は処理を拒否し、「the skills are behind this workspace; update them first」と表示してアップグレードをそこで停止します。ダウングレードは行いません。workflows/ とテンプレートの templates/ を比較します(node scripts/template.mjs でテンプレートのフォルダーが表示されます)。異なる点を伝えます。Postgres ランタイム導入前のワークスペース(db/tables/cache.ts があるもの)は、この作業ではアップグレードしません。ユーザーの同意後、updates の説明に従って移行します。テンプレートが管理する lib/、server/、viewer/、connections-ui/、share-server/(残っている viewer-server/ は削除)、scripts/、drizzle-runtime/、nitro.config.ts、drizzle.config.ts、drizzle-runtime.config.ts、tsconfig.json、share-firewall.json を更新し、リリースで廃止されたテンプレートファイルだけを削除します(0.2.7 では runtime フォルダーを廃止:lib/workflow-folders.ts、lib/shared-folders.ts、lib/shared-folder-transport.ts、lib/shared-folder-service.ts、server/api/workflow-folders.ts。ワークスペース独自の lib/ 内ファイルは残します)。ワークスペースに skills/ がない場合は、テンプレートからコピーします。ワークスペースのルートにある .gitignore と .github/workflows/check.yml を root/ の内容で更新します。ワークスペースが追加した CI 手順は保持します。runtime reliability に従い、package.json の依存関係と起動スクリプトを統合します。ユーザーが追加した依存関係とカスタムコマンドを保持したうえで、テンプレートの package-lock.json をワークスペースにコピーし、node_modules を削除して npm install を実行し、npm ci --dry-run で確認します。古いロックファイルに重ねてインストールすると、他のプラットフォームのパッケージが削除され、ホスト環境のビルドが壊れます。また、何もない状態から生成したロックファイルは npm ci で拒否されます。workflows/index.ts、db/tables/index.ts、skills/index.ts を再生成します。インポートしたメタデータファイルを含め、各ワークフローのエントリにある viewer、data、intake、その他の作成済みプロパティは保持します。ワークスペースで記述された workflows/groups.ts はそのまま維持します(共通セットアップでは、ファイルがない場合に空のファイルを追加します)。ただし、0.2.7 からのアップグレードでは、そのファイルに記載されたステージを一覧から削除します。ステージは親パイプラインの下に表示されるようになったためです。どのステージが移動したかを伝えます(ビルド時に「 is a stage of …」と各ステージが表示されます)。workflows/、db/tables/、skills/、drizzle/、.env、data/ のほかのファイルには触れません。vercel.json はテンプレート管理のファイルですが、crons は共通セットアップで統合します。生成アセットと .env.* の無視対象(lib/criteria.generated.ts を含む)を統合します。Keys の指定に従って共通セットアップの --local を実行します。npm run viewer:register は ID のないエントリに対してのみ実行します。0.2.6 以前からのアップグレードでは、local and production の説明に従ってワークフローフォルダーをグループに変換します(node scripts/folders-to-groups.mjs を実行し、どのフォルダーにもワークフローがない場合は --suggest を指定します。提案されたグループを表示して保存し、その後 data/workflow-folder-mode.json を削除します)。ビルドし、npm run dev を一度起動してローカルデータベースをマイグレーションしてから、ホスト上のプライベートビルドと共有ビルドを検証します。既存のワークフローをそれぞれ確認し、ビルド前に businessGraph と description を追加または修正します。export const criteria、またはコード内に記述された ICP/ペルソナのルールがある場合は、Criteria の説明に従って readIcp/readPersona に移し、変更したワークフローを伝えます。すべてのワークフロー ID を保持します。npm run dev でローカルサーバーを再起動し、起動設定と Diagram ページを検証します。ホスト環境のアップグレードでは、準備状況の確認後にデプロイ済みコピーを検証し、ホスト上のセットアップを再実行します。これにより share rate limits が再適用されます。
グループグループは workflows/groups.ts にあります(viewer)。階層は 1 段のみで、各ワークフローは最大 1 つのグループに所属し、ファイル内の順序が画面上の順序になります。単独で機能するワークフローだけを一覧にします(別のワークフローからしか開始されないステージは一覧に含めません。開始するワークフローのグループ内に、そのワークフローの下位として表示されます)。作成時は、新しいワークフローが既存のワークフローと共有するものに基づき、計画でグループを提案します。既存のワークフローが同じテーブルに書き込む、または同じテーブルを読み取るグループがあればそのグループを使います。なければ作業名を付けた新しいグループを作成し、単独で機能する場合はグループなしにします。新しいステージにグループは不要です。パイプラインの下に表示されることを伝えます。「X を Y に移動」「Y を分割」「Y の名前を変更」「これらを新しいグループに入れる」は、そのファイルを編集する依頼です。変更内容を一文で伝え、編集してビルドします(node scripts/build-viewer.mjs は未知のスラッグ、一覧に含まれるステージ、複数グループに属するワークフロー、空のグループがある場合に処理を拒否します)。コミットし、グループへのリンクを添えて締めくくります。「 の状況は?」と尋ねられた場合は、GET /api/link/group/<id> から runsUrl を取得し、ワークスペースの Runs 読み取りと、各ワークフローの最終実行に対する op=summary を参照します(ホスト環境では Runs 読み取りに /api/viewer/service?v=3&op=workspaceRuns&group=<id> を使用します)。その実行結果を基に、グループへのリンクを添えて回答します。グループ用ストア、移動ボタン、フォルダー、タグは決して追加しません。
削除ワークフローファイル、そのレジストリエントリ、workflows/groups.ts 内のスラッグ(削除によってグループが空になる場合はそのグループも)、vercel.json の cron を削除します。そのワークフローがステージを開始していた場合、ステージは単独で機能するようになります。代わりにそのグループに一覧表示するか、Ungrouped に移動することを伝えます。テーブルとそのデータは保持し、その旨を伝えます。プロジェクトが接続済みの場合は、保存時のデプロイでホスト上のコピーからそのワークフローとスケジュールが削除されることを伝えます。
Create、Update、Upgrade については、viewer を参照してください。有効な業務図と、各 Data タブに有効な viewer.sharePolicy を保持してください。保存前にビルドしてください。共有メタデータの欠落や不一致は、作成時のエラーです。ポリシーを準備すると Data を選択できるようになります。公開リンクのアクセス権を変更する場合は、引き続き明示的な共有リクエストが必要です。

保存のたびに、変更内容を一文で説明し、origin/main が存在する場合は先に pull し、ホストの書き込み経路を通じて編集し、平易なメッセージを付けて main に commit し、リモートが存在する場合は push してください。commit を確認し(リモートが存在する場合は origin/main に反映されたことも確認し)、最後に作成、変更、削除した内容を伝えてください。

ローカルでの実行はないと明示しているホストでは、値はホストの環境にあります(scaffold はどのホストでも env.example を提供しません)。各実行は、push 後かつ Deploy の準備完了チェック後に、デプロイ済みのコピーを対象にします。Upgrade ではサーバーを再起動する代わりに、そのチェック後にデプロイ済みの図のページで確認します。このようなホストでは、エージェントがほかに何を行う場合でも、次の 2 つのルールが適用されます。

  • リンク:確認のために開発サーバーやローカルビルドを起動してもかまいませんが、そこで配信されるものを投稿してはいけません。返信に含められるのは、準備完了を待った後にデプロイ済みコピーのリンクルートが返した、確認済みの viewerUrl だけです。返信に localhost を含めてはいけません。
  • キー:未使用のサービスも含め、存在の有無と宣言された用途を確認するには、保護されたワークフローのトランスポート経由で GET /api/connections を読み取ってください。サービス名には保存済みの Note を使用し、コードには正確な変数名を使用してください。Connections の命名規則 に従ってください。キーが不足している場合は、プライベートリンクルートの確認済み connectionsUrl から直接入力してください。チャットでキーを収集してはいけません。保存した変更は、意図的にデプロイした後に有効になります。存在していることは、有効であることの証明にはなりません。
コードで採用されている規約
  • 関連付けられた結果テーブル:linked data では、任意の data レジストリプロパティと、People/Companies 形式の読み取り専用ビューアについて説明しています。ユーザーが関連レコードを閲覧する必要がある場合は登録してください。そのプライベートな Data リンクは、同じリンクルートから取得します。アップグレードでは viewer、data、intake を保持してください。共有はプライベートビューアで明示的に行う操作です。viewer で説明されている、バージョン管理されたテーブル/列/リレーションシップ/行のポリシーが必要です。
  • ステップの選択:各ステップには、目的を果たす最もシンプルな種類を使います。決定的な処理(解析、算術処理、フェッチ、入力が既知のプロバイダーまたはゲートウェイ API 呼び出し、Slack への投稿)は、モデルを使わない通常の "use step" 関数にします。ワークフローがすでに保持しているテキストに対する判断(スコアリング、分類、抽出、下書き作成)は、スキーマを指定した generateObject による単発の AI ステップにします。エージェントステージ(runAgent)を使うのは、ユーザーがエージェントを指定した場合、またはモデルが進行に応じて自らツール呼び出しを選ぶ必要がある場合(適切なエンドポイントの特定、複数ページにわたる調査)で、通常のステップと AI ステップの組み合わせを事前に記述できない場合に限ります。常に同じツールを同じ順序で呼び出すステージは、それぞれのステップとして実装します。ユーザーが、ステップで済む処理にエージェントを求めた場合は、その旨を一文で伝え、依頼どおりに構築します。
  • 行の取得元は、defaultInput(インライン)、"use step" 関数内のプロバイダーまたは API 呼び出し、別のワークフローが入力するテーブル、または受信 Webhook(lib/intake.ts の export const intake = defineIntake({ secretEnv, signature, eventId, toRow }) を使い、workflows/index.ts で intake として登録)です。POST /api/intake/<slug> は、生のボディに対する送信元の署名を検証し、イベント ID による30日間の再配信を除外して、マッピング済みの行で実行を1回開始します。送信元は公開共有プロジェクトに投稿し、そこから署名付きイベントを Vercel Authentication を経由しないように中継します。作成または編集した後は必ず、送信元の設定方法を deploy.md でユーザーに案内します。ワークスペースファイルやローカル限定データから行を取得してはいけません。入力は lib/rows.ts の RowsInput、{ rows?, maxRows?, maxSpendUsd? } です。各行は、テーブルの主キーである必須の文字列 key を持つオブジェクトです。ワークフローの定数がデフォルト値になります。開始ルートは POST ボディを defaultInput にマージするため、制限付き実行には POST { maxRows: 1 } を使います。
  • lib/rows.ts の runRows({ rows, table, step, maxRows, maxSpendUsd, estimateUsd, freshForMs, concurrency?, saveEvery?, fanOut? }) がループ処理です。step(row) はワークフローのスコープ内に置く通常の非同期関数で、"use step" 関数を順番に待機し、{ ...columns, costUsd } を返します。テーブルは名前で渡し、db/tables/index.ts で解決します。完了した行は、エンジンの各ステップで1ホップ分のコストが発生するため、10件ずつ1つのステップで保存します(saveEvery)。保存前にクラッシュしても、エンジンは完了済みのステップを再実行するため、失われるものはありません。すべてのワークフローで fanOut: { workflow: <its own function>, input, chunkSize } を渡します。その件数を超える場合、実行はリストを自身の子実行に分割するだけで、同時に4件ずつ(各ウェーブを1つのステップで開始)処理します。各子実行には上限の正確な割当分を渡し、結果を合算するため、どのような件数のリストでも1回の実行と1つの結果になります。通常のステップだけで構成されるワークフローでは chunkSize を100、エージェントステージを含むワークフローでは20にします。エンジンは1回の実行を25,000イベントに制限しており、エージェントを使う1行の処理では約100イベントを消費します。親をキャンセルすると子もキャンセルされます。
  • すべての結果テーブルには key、updated_at、cost_usd、error があります。データベースへのすべての入出力、すべての cached() 呼び出し、generateObject 呼び出しは、async function name() { "use step"; } として宣言した "use step" 関数内で実行します。アロー関数形式やメソッド形式は使いません。有料または AI を使うすべてのステップで name.maxRetries = 0 を設定します。
  • 読み取りは一度だけ、少量に抑えます。Postgres がアプリに送るすべてのバイトが Neon のデータ転送量に加算されるため、読み取りでは列を指定します(幅の広いテーブルに対して select() だけを使わず、db().select({ key: t.key, score: t.score }) のように指定します。プロフィールを取得する場合は getProfile(db, entity, key, { columns }) を使います)。フィルタリング、件数の取得、集計は SQL(count(*)::int、jsonb_array_elements、= ANY(...))で実行します。ステップでは必要なデータを一度読み込んで保持し、項目ごとに行を再読み込みしません。リストはページネーションし、ステップでテーブル全体を Node に読み込んでループ処理してはいけません。各読み取り経路に適用される予算は lib/read-budgets.ts にあります。このスキルの tests/read-budgets.test.ts がその遵守を検証します。また、local では、リリース前にワークフロー独自の読み取り量を測定する方法を説明しています。
  • エージェントステージ:ワークフロー内のエージェントには、必ず lib/agent.ts の runAgent() を使います。ワークフローのスコープ内に置いた通常の非同期関数(ステージ関数、agent ノード)から呼び出し、WorkflowAgent を直接使ったり、"use step" 関数内から呼び出したりしてはいけません。このヘルパーはすべてのモデル呼び出しとツール呼び出しをステップにし、時間制限と sleep() を競合させ、スキーマを整え、実際のコストを返します。設定項目がオーサリングで指定できるすべての内容です。model と reasoning(model を省略すると、次のルールに従って lib/models.ts の gtmModel() がデフォルトになります。reasoning は GTM_REASONING、それがなければ high がデフォルトです)、instructions、skills(skills/index.ts にある名前を指定し、それぞれ skills/ 配下のテキストモジュールです)、tools(url、keyEnv、allow、maxCalls を指定する名前付きの mcp サーバー。web.fetch は無料のステップです。web.search は AI Gateway(true または "gateway"。Exa を使い、どのモデルでも使用でき、キーは不要)または OpenAI("openai"。openai/* モデルのみ)によって実行されます。ステップではなくモデル呼び出し内で実行されるため、承認や呼び出し回数の制限を適用できません。execute が "use step" 関数である custom ツール)、approve(破壊的な操作の確認、または明示的に求められたワークフローのレビューが必要なツール名を指定します。通常の承認ゲートはデフォルトで追加しません。行はフックで待機し、実行の読み取りルートでは、POST /api/runs/<id>/approve で判断が下されるまでリクエストが一覧表示されます。承認待ちが発生する場合は timeout を日単位で設定します)、stream(GET /api/runs/<id>/stream でモデルとツールの全イベントをストリーミングします)、maxSteps、maxUsd(ソフト制限です。この値を超える呼び出しの後、エージェントはツールの使用を停止し、そこまでに得た内容をまとめます)、timeout(期間を表す文字列です。行は失敗します)、schema(プレーンテキストの場合は指定しません)、prompt または messages、さらに WorkflowAgent が受け付けるその他の項目には agent(コンストラクターオプション:sampling、プロバイダーオプション、prepareStep、prepareCall、コールバック、テレメトリー、コンテキスト)と call(呼び出しごとのオプション:toolChoice、activeTools、変換)があります。スキーマでは省略可能なフィールドではなく nullable フィールドを使い、文字列形式を指定しません(.url() や .email() ではなく z.string() を使います)。意図は説明文に記載します。SDK に timeout: や AbortSignal.timeout() を渡してはいけません。MCP クライアントやツールを手作業で構築してはいけません。参考例は example-research.ts です。
  • 単発の AI ステップは、ステップ内で generateObject({ model: gtmModel(), ... }) を使います。ツールを使う処理はすべて runAgent ステージにします。ワークフローのコードでモデル ID を指定したり、GTM_MODEL を直接読み込んだりしてはいけません。モデル ID を置く場所は lib/models.ts だけです。gtmModel() は、ユーザーがモデルを選択している場合は GTM_MODEL を返します。それ以外の場合は GTM_AGENT_BACKEND に応じたデフォルトを返します。claude なら最新の Claude Haiku、codex またはそれ以外なら GPT-6 Luna です。そのため、ホストされたコピーでも作者がローカルで使っているモデル系列が維持されます。setup --deploy は GTM_AGENT_BACKEND を Production にコピーし、そこでデフォルトの選択にのみ使用します。ホストされたコピーで使うモデルをユーザーが指定した場合は、コードではなく Vercel プロジェクトの Production に GTM_MODEL を設定します。ステージごとの model は、そのステージで本当に異なるモデルが必要な場合に限って使います。ステージのバックエンドは、固定された環境から実行ごとに決まります。GTM_AGENT_BACKEND が claude または codex の場合は、作者のサブスクリプションを使い、1ステップで実行し、このマシン上でのみ動作します。MCP サーバーと Web ツールは引き継がれます。codex では、各 MCP サーバーの allow リストが必要です。未設定の場合は Gateway を使います。カスタムツール、approve、stream、または messages を使うステージと、ホストされたコピーのすべてのステージは、いずれの場合も Gateway 上で実行されます。ステージの backend は、そのステージだけで環境変数を上書きします。ローカルかホスト環境かを選ぶためだけに backend を指定してはいけません。その選択は環境変数が行います。ほかに AI の経路はありません。
  • 条件:ワークフローのコードに ICP やペルソナを複製してはいけません(ファイルに記載された役職名のリスト、規模の上限、ルール文などをコードに含めません)。実行開始時にスラッグで読み込みます。lib/criteria.ts の readIcp("<slug>") または readPersona("<slug>") を、runRows の前にワークフローのスコープ内で一度呼び出し、その結果を行のステップに渡します。それぞれ { name, text, fields, signals, disqualifiers } を返します。text は AI ステップのプロンプトに使うファイルの内容です。fields には、記載された各フィールドがラベルごとに格納されます(Unknown のフィールドは含まれません)。items(fields["Job titles"]) はリストを分割します。ルールステップでは、そこから役職名、規模、所在地、除外条件を取得します。ルールステップは、行から判定できる記載済みフィールドをすべて確認します。また、確認できなかった記載済みフィールド(たとえば、行に言語情報がない場合のペルソナの Languages)は、理由に名前を挙げます。いずれかを黙って省略してはいけません。ローカル実行では毎回ファイルを読み込みます。ビルド時に lib/criteria.generated.ts(gitignore 対象)に埋め込まれるため、ICP またはペルソナの編集内容は、プッシュ後にデプロイが完了すると、ホストされたコピーの次回実行に反映されます。freshForMs の期間内にある行は、古い条件で作成されたスコアを保持します。ファイルが見つからない場合は、その名前を示して実行を失敗させます。
  • ドキュメントコメント:1行目にタイトル、2段落目に1文の概要を記載します。図のページでは viewer.description がない場合、概要が代わりに表示されます。
  • ワークフローの説明:Create、Update、Upgrade の際に、ワークフロー全体の処理内容を平易な言葉で説明する viewer.description を記述します。長さは約280文字、500文字以下にします(500文字を超えるとビルドが失敗します)。変更によって説明が事実と異なるものになった場合は書き直します。viewer を参照してください。
  • Viewer メタデータ:安定したノード ID、人が理解しやすいラベル、入力/アクション/判断/出力の種類、説明、意味のある判断エッジを含む viewer.businessGraph をリテラルとして記述します。プロバイダーやキャッシュの詳細は、それらを明示する専用フィールドに記載します。Create、Update、Upgrade の際に、図を実際のワークフローコードと照合します。viewer.id は保持してください。スキーマと検証については viewer を参照してください。
  • 参照先:エントリーリンク に従い、作成・変更後、デプロイ・アップグレード後、通常の実行後、明示的な依頼を受けた後に確認します。正式な非公開 viewerUrl を Open GTM Workflows として返します。これは外部向け共有権限の付与とは別です。
  • 接続:有料または AI を使うステップを作成する前、および実行前のすべての確認で、対象の接続一覧を読み込みます。接続が不足している場合は一度だけ名前を挙げ、信頼できる Connections フォームを開きます。どのキーが必要か判断する際は、ワークフローで宣言されたゲートウェイとの関係を使います。ワークフローの Connections タブで各接続の設定状況または不足状況を表示できるように、コードが読み込むキーごとに1エントリーを持つ viewer.connections をビジネスグラフと並べてリテラルとして記述します。未確認のキー、アクティベーション状態、安全な認証情報の入力については Connections に従ってください。
  • ゲートウェイ:ホストが公開するゲートウェイツール(データマーケットプレイス、MCP サーバーなど)経由でプロバイダーを利用する有料ステップでは、コードからゲートウェイ独自のキーを使ってゲートウェイを呼び出します。Connections で管理される <GATEWAY>_API_KEY を使い、背後にあるプロバイダーを直接呼び出してはいけません。ゲートウェイの HTTP API が不明な場合は、ステップを作成する前にドキュメントを確認します。推測してはいけません。
  • エンジン機能はネイティブに使用します(local.md を参照)。フックまたは sleep は wait ノード、子ワークフローは sub ノード、runAgent ステージは agent ノードです。
  • 人への連絡:lib/notify.ts の notify({ kind, text, approval?, target }) は、GTM エージェントの通知ルートに投稿します。このルートは、モデルを呼び出さずに、エージェントのボットトークンを使ってテキストを直接 Slack に投稿します。tell と show は通常の投稿です。ask と handoff はメッセージを開き、エージェントがそのスレッドを監視するため、そこへの人の返信でエージェントが起動します。ステージでの承認は、ワークフロープロジェクトに GTM_AGENT_URL と GTM_NOTIFY_SECRET が設定されている場合、自動的に通知されます。投稿先はコードで指定します。ワークフローの先頭に const NOTIFY = { channelId: "C0…" } を置き、各ステージには notify: input.notify ?? NOTIFY として渡し、各 notify 呼び出しには target として渡します。投稿はチャンネルのトップレベルに行われ、実行を開始した会話内には投稿されません。行ごとの通知には runRows を使います。ステップ内で notify を呼び出してはいけません。指定は notify: { target: input.notify ?? NOTIFY, every: "chunk", line: (row, columns) => … } とします。every は row(完了した行ごとに1件投稿)、chunk(行の実行ごとに1件投稿。ファンアウト時は子実行ごとに1件。提案時のデフォルト)、または run(最後に合計を1件投稿)のいずれかです。件数を伝え、判断は含めません。line は文字列、または行にリッチな投稿が適している場合は { text, blocks } を返します。ステージに notify: false を指定すると、そのステージの承認通知は送られません。ワークフローが投稿先を指定しない場合に限り、エージェントプロジェクトの GTM_NOTIFY_CHANNEL がフォールバックとして使われます。ワークフローがエージェントを呼び出すのは人に連絡するためだけであり、判断させてはいけません。
  • lib/ へのヘルパーの追加は、SDK の呼び出しをそのまま使うと失敗するか二重に課金されることが確認された場合に限ります。それ以外はすべて、patterns の実例にあるように、ネイティブの SDK 呼び出しを使います。
  • ルート(ホスト環境では Vercel Authentication の背後にあり、ノート PC の vercel curl またはホストされたエージェントからホストのバイパスを使ってアクセスします。ローカルではパスワード不要で、このコンピューターからのみアクセスでき、ほかの Web サイトから変更することはできません):POST /api/run/<slug>、GET /api/run/<slug>(Vercel Cron 専用。CRON_SECRET が必要で、ローカルでは拒否されます)、POST /api/intake/<slug>(ベアラー認証なし。送信元の署名を使います。送信元は共有プロジェクトのリレーを使います)、GET /api/runs/<id>(状態、出力、エラー、および approvals。未処理の承認リクエストを先に表示)、POST /api/runs/<id>/approve と { token, approved, reason? }、GET /api/runs/<id>/stream(エージェントステージのストリーミング中、1行に1つの JSON イベントを返します)、POST /api/runs/<id>/cancel、GET /api/link/<slug>、GET /api/link/group/<id>。ベース URL はローカルでは http://localhost:3939、デプロイ済みのコピーでは GTM_WORKFLOW_URL です。GTM_AGENT_HOSTED が 1 の場合、ホストはエージェントからアクセスできないすべての呼び出しに Vercel の保護バイパスを追加します。認証情報は送信しないでください。

出力

workflows/<slug>.ts、そのテーブルとマイグレーション、レジストリーのエントリー、workflows/groups.ts 内のグループ、スケジュール実行する場合は vercel.json の cron、図のページ、結果テーブルの行、そしてプロジェクトを接続した後は、すべてのプッシュで更新されるデプロイ済みコピーです。

キュー、プロバイダー、MCP、または CLI の障害については、原因を特定したり再試行を提案したりする前に、実行時の信頼性を読んでください。

例外

このスキルと一緒に gtm-workspace スキルをインストールする必要があります。../gtm-workspace/SKILL.md が見つからない場合は、このスキルをインストールしたのと同じ方法で npx skills add eliasstravik/gtm-skills -s gtm-workspace -y を実行してインストールするよう伝えてください(このスキルがグローバルのスキルディレクトリにある場合は -g を追加します)。その後、再試行します。キーが見つからない場合、実行は開始前に停止し、該当するキーが示されます。DATABASE_URL が設定されていない状態で Vercel 上で本番ビルドを実行すると、意図的に失敗します。そのことを報告し、deploy.md の説明にあるように、Neon インテグレーションを通じてデータベースを追加すると伝えてください。デプロイ済みコピーで実行するには、稼働中のプロジェクトが必要です(コンピューター上ではリンク済みの workflows/.vercel/project.json、ホストされたエージェントでは GTM_WORKFLOW_URL)。プロジェクトがない場合は、代わりに Deploy と同じ方法で稼働させる手順を伝えてください(CLI にサインイン済みのコンピューターで共有セットアップ --deploy を実行します。gtm-agent は任意です)。workflows/ に scripts/gtm.ts が含まれている場合、それは以前のランタイムです。Upgrade はこれに手を加えません。updates の移行を案内してください(ワークスペースの履歴が保持される場所に退避すると、次のプッシュまでデプロイ済みコピーも稼働し続けます。その後、現在のランタイム上で再構築します)。

QC

  • すべてのワークフローに、実際のコードとラベル、分岐、結果が一致する有効なビジネスグラフがあります。ビジネス上の動作を変更した場合は、同じ変更内でメタデータも更新します。メタデータのビルドが成功します。コンパイラーのグラフでビジネスメタデータの欠落を補うことはできません。
  • すべてのステップで、処理に必要な最も単純な種類を使います。決定論的な処理に AI ステップを使わず、ユーザーがエージェントを指定していない限り、通常のステップと AI ステップを固定順序で実行すれば済む場面でエージェントステージを使いません。
  • 新規または変更されたワークフローで複数行を初めて実行する前に、質問ツールを通じて1行のテストを提案します。1行のリクエストではその質問をせずに実行します。実行のたびに、費用に関する説明を実行前に提示します。
  • 結果テーブルには固定の4列があります。有料ステップと AI ステップでは maxRetries = 0 を設定します。ワークフローのスコープ内に cached() や generateObject の呼び出しを置きません。
  • すべてのエージェントステージは、ワークフローのスコープ内で runAgent() を呼び出し、maxSteps、maxUsd、timeout を設定します。WorkflowAgent のインポート、timeout: オプション、AbortSignal.timeout、スキーマ内の .url() や .email()、出力スキーマ内のオプショナルフィールドは使用しません。新規または変更されたエージェントステージは1行でテストし、返信でそのツール呼び出し、停止理由、実際の費用を明記します。
  • すべてのワークフローで、自身を指定した fanOut を渡します。エージェントステージがある場合は chunkSize を20にします。ワークフローがインポートするモジュールは、"use step" 関数の外部でデータベースにアクセスしません。ルート専用のコードは *-api.ts ファイルに置きます。
  • 通常の実行への返信は結果で終え、項目のアドレスが変更された場合またはユーザーが明示的に求めた場合を除き、項目を繰り返しません。保存への返信では、作成、変更、削除した内容で締めくくります。

参考資料

interactions は対話、local and production は本番環境に到達するネイティブコマンド、imports はファイルの各行で開始する実行である CSV インポート、local.md は起動、キー、データ、スケジュール、テーブル、ビューアー、エージェントステージ、ファンアウト、インテイク、通知、調査結果の台帳について説明しています。patterns は実例付きのネイティブ SDK 呼び出し、deploy.md はデプロイについて説明しています。実装例としてテンプレートの templates/workflows/example-scores.ts を、エージェントステージの参考例として templates/workflows/example-research.ts を参照してください(node scripts/template.mjs を実行するとフォルダーが表示されます)。gtm-workspace の参考資料:interaction、contract。

コメント