Agent Script Recipe (Agent Scriptのサンプル集) のAIコーディングツール用ルールファイル Agent Script Rules & Guideを元に、Agent Scriptの書き方について解説します。(2026年1月11日時点)
Agentforce Vibes, Cursor, Windsurf, Claude Code等のAIエディタで使用する場合は、上記ファイル をルールとして読み込ませて利用できます。本記事は、このルールファイルを人間が理解しやすいように翻訳したものです。
Agent Script の正確な仕様については、公式ドキュメントを参照してください
Agent Script ルール & ガイド
ファイル構造とブロック順序
トップレベルの8つのブロックは必ず以下の順序で記述しましょう。
# 1. CONFIG (必須) - エージェントのメタデータ
config:
agent_name: "DescriptiveName"
...
# 2. VARIABLES (任意) - 状態管理
variables:
...
# 3. SYSTEM (必須) - グローバル設定
system:
messages:
welcome: "..."
error: "..."
instructions: "..."
# 4. CONNECTIONS (任意) - エスカレーションの設定
connections:
...
# 5. KNOWLEDGE (任意) - ナレッジベースの設定
knowledge:
...
# 6. LANGUAGE (任意) - 言語設定
language:
...
# 7. START_AGENT (必須) - 最初の振り分け先トピック
start_agent topic_selector:
description: "..."
reasoning:
actions:
...
# 8. TOPICS (少なくとも1つ必須) - 各トピックの定義
topic my_topic:
description: "..."
actions:
...
reasoning:
...
ブロック内部の順序
start_agent、 topic ブロック内
description(必須) トピックの説明-
system(任意) トピック固有の指示上書き -
actions(任意) トピック内で使用可能なアクション定義 reasoning(必須) LLMの思考ロジック・指示-
after_reasoning(任意) 推論後の処理
reasoning ブロック内
instructions(必須) 自然言語による指示-
actions(任意) 選択可能なアクションのリスト
必須要件
すべてのAgent Scriptには必ず以下を含めましょう。
-
configブロック(agent_nameが必須) -
systemブロック(messages.welcome,messages.error,instructionsが必須) -
start_agentブロック(description,reasoning.actionsが必須) - 少なくとも1つの
topicブロック(description,reasoningが必須)
命名規則
すべての名前(エージェント名、トピック名、変数名、アクション名等)に適用されるルールです。
- 英字、数字、アンダースコアのみ使用可
- 必ず英字で始まること
- スペースは禁止
- アンダースコアで終わることはできない
- アンダースコアを2つ続けることはできない
- 最大80文字まで
インデントとコメント
- スペースを使用(タブは不可)
- 推奨:1レベルにつきスペース3つ
- ファイル全体で一貫したインデントを維持すること
-
#でコメントを記述(Pythonスタイル)
インデントとコメントの例
# これはコメントです
config:
agent_name: "My_Agent" # インラインコメントも可能
各ブロックの詳細
configブロック
config:
# 必須
agent_name: "DescriptiveName" # 一意の識別子(英数字、アンダースコア)
# 任意(デフォルト値あり)
agent_label: "DescriptiveName" # 表示名(デフォルトはagent_name)
description: "Agent description" # エージェントの説明
agent_type: "AgentforceServiceAgent" # または "AgentforceEmployeeAgent"
default_agent_user: "user@example.com" # AgentforceServiceAgentの場合は必須
variables ブロック
variables:
# MUTABLE 変数 - エージェントが読み書き可能(デフォルト値が必須)
my_string: mutable string = ""
description: "スロットフィリングのための説明"
my_number: mutable number = 0
my_bool: mutable boolean = False
my_list: mutable list[string] = []
my_object: mutable object = {}
# LINKED 変数 - 外部コンテキストからの読み取り専用(sourceが必須、デフォルト値は不可)
session_id: linked string
description: "セッションID"
source: @session.sessionID
型サポート一覧
| 型 | Mutable | Linked | Actions |
|---|---|---|---|
| string | ✅ | ✅ | ✅ |
| number | ✅ | ✅ | ✅ |
| boolean | ✅ | ✅ | ✅ |
| object | ✅ | ❌ | ✅ |
| date | ✅ | ✅ | ✅ |
| timestamp | ✅ | ✅ | ✅ |
| currency | ✅ | ✅ | ✅ |
| id | ✅ | ✅ | ✅ |
| list[T] | ✅ | ❌ | ✅ |
| datetime | ❌ | ❌ | ✅ |
| time | ❌ | ❌ | ✅ |
| integer | ❌ | ❌ | ✅ |
| long | ❌ | ❌ | ✅ |
Boolean値
Boolean値は必ず頭文字を大文字にする:True または False (true や false は不可)
system ブロック
system:
messages:
welcome: "会話開始時に表示されるウェルカムメッセージ"
error: "問題発生時に表示されるエラーメッセージ"
# 1行または複数行の指示
instructions: "あなたは役立つアシスタントです。"
# パイプ(|)を使用した複数行記述
instructions:|
あなたは役立つエージェントです。
常に礼儀正しく、プロフェッショナルとしてふるまってください。
機密情報は絶対に共有しないでください。
topic ブロック
topic my_topic:
description: "このトピックが扱う内容の説明"
# 任意: このトピック専用のシステム指示(システム全体の指示を上書き)
system:
instructions: "トピック固有の指示"
# アクション定義(このトピック内で呼び出し可能なアクション)
actions:
action_name:
description: "このアクションが何をするか"
inputs:
param1: string
description: "パラメータの説明"
param2: number
outputs:
result: string
target: "flow://MyFlow"
# 必須: 推論設定
reasoning:
instructions:->
| 常に表示される静的な指示
if @variables.some_condition:
| 条件付きの指示
| 変数を埋め込むテンプレート: {!@variables.value}
# 推論中にLLMが使用できるアクション
actions:
action_alias: @actions.action_name
description: "説明の上書き"
available when @variables.condition == True
with param1=... # ...はLLMが値を抽出(スロットフィリング)
with param2=@variables.x # 特定の変数にバインド
set @variables.y = @outputs.result
# 任意: 推論完了後に実行される処理
after_reasoning:
if @variables.should_transition:
transition to @topic.next_topic
アクション定義
targetのフォーマット
| Short | Long | 用途 |
|---|---|---|
| flow | flow | Salesforce Flow |
| apex | apex | Apex Class |
| prompt | generatePromptResponse | Prompt Template |
| standardInvocableAction | standardInvocableAction | 標準アクション |
| externalService | externalService | 外部API |
| quickAction | quickAction | クイックアクション |
| api | api | REST API |
| apexRest | apexRest | Apex REST |
その他: serviceCatalog, integrationProcedureAction, expressionSet, cdpMlPrediction, externalConnector, slack, namedQuery, auraEnabled, mcpTool, retriever
完全なアクション構文
actions:
get_customer:
description: "顧客情報を取得する"
label: "Get Customer"
require_user_confirmation: False # 実行前にユーザー確認を求めるか
include_in_progress_indicator: True # 処理中にプログレスインジケーターを表示するか
progress_indicator_message: "Looking up customer..."
inputs:
customer_id: string
description: "顧客の一意なID"
label: "Customer ID"
is_required: True
outputs:
name: string
description: "顧客名"
email: string
description: "顧客Email"
filter_from_agent: False # エージェントに見せないようにするか
is_displayable: True # ユーザーに表示可能か
target: "flow://GetCustomerInfo"
推論アクション
reasoning ブロック内でのアクション呼び出し設定です。
入力バインディング
reasoning:
actions:
# すべてスロットフィリングを使用
search: @actions.search_products
with query=...
with category=...
# 固定値や変数バインドとスロットフィリングが混在
lookup: @actions.lookup_customer
with customer_id=@variables.current_customer_id # 変数バインド
with include_history=... # スロットフィリング
with limit=10 # 固定値
... はLLMに「会話の内容から適切な値を抽出して」という意味 = スロットフィリング
アクション実行後の処理
@actions.* に対してのみ有効です。(@utils.* には使用不可)
reasoning:
actions:
process: @actions.process_order
with order_id=@variables.order_id
# 出力値を変数にセット
set @variables.status = @outputs.status
set @variables.total = @outputs.total
# 次のアクションを連鎖実行
run @actions.send_notification
with message="Order processed"
set @variables.notified = @outputs.sent
# 条件付き遷移
if @outputs.needs_review:
transition to @topic.review
Utility アクション
reasoning.actions でのみ使用可能な組み込み機能です。
| ユーティリティ | 目的 | 構文 |
|---|---|---|
| @utils.escalate | 人間へのエスカレーション | name: @utils.escalate |
| @utils.transition to | 永続的なトピック遷移(戻らない) | name:@utils.transition to @topic.X |
| @utils.setVariables | 変数セット | name: @utils.setVariables (引数 with var=...) |
| @topic."name" | トピック遷移(戻ってくる) | name: @topic.X |
reasoning:
actions:
# 永続的なトピック遷移(もどらない)
go_to_checkout: @utils.transition to @topic.checkout
description: "準備ができたらチェックアウトへ移動"
available when @variables.cart_has_items == True
# 人間へエスカレーション
get_help: @utils.escalate
description: "人間のエージェントに接続"
available when @variables.needs_human == True
# トピック遷移(戻ってくる)
consult_expert: @topic.expert_topic
description: "専門トピックに相談する"
# LLMによる変数セット
collect_info: @utils.setVariables
description: "ユーザー設定を収集"
with preferred_color=...
with budget=...
遷移構文のルール
重要:場所により構文が異なります
reasoning.actions で使う場合
# 必ず @utils をつける
go_next: @utils.transition to @topic.target_topic
description: "LLM向けの説明"
after_reasoning で使う場合
# @utils はつけない
transition to @topic.target_topic
- ディレクティブブロックでは
@utils.transition toは使えません -
reasoning.actionsではtransition toは使えません。
フロー制御
instructions での条件分岐
else if は現在サポートされていません
instructions:->
| アシスタントへようこそ!
if @variables.user_name:
| こんにちは、{!@variables.user_name}さん!
else:
| お名前を教えていただけますか?
if @variables.is_premium:
| プレミアム会員向けの機能をご利用いただけます。
ディレクティブブロック内の遷移
after_reasoning:
if @variables.completed:
transition to @topic.summary
アクションの有効条件
reasoning:
actions:
admin_action: @actions.admin_function
available when @variables.user_role == "admin"
premium_feature: @actions.premium_function
available when @variables.is_premium == True
テンプレートと式
文字列テンプレート
{!expression} を使用して変数を埋め込みます。
instructions:->
| 合計金額: {!@variables.total}
| 品数: {!@variables.cart_items}
| ステータス: {!@variables.status if @variables.status else "pending"}
複数行文字列
| を使用します。
instructions:|
1行目
2行目
3行目
または、
instructions:->
| 1行目
1行目の続き
| ここから2行目がはじまる
サポートされる演算子
| カテゴリ | 演算子 |
|---|---|
| 比較 | ==, !=, <, <=, >, >=, is, is not |
| 論理 |
and, or, not
|
| 算術 |
+, - (*, /, % は無し) |
| アクセス |
. (プロパティ), [] (インデックス) |
| 条件 |
x if condition else y (三項演算子のような記述) |
リソース参照
-
@actions.<name>: トピックのactionsブロックで定義されたアクション -
@topic.<name>: トピック名 -
@variables.<name>: 変数名 -
@outputs.<name>: アクションの出力(アクション実行後コンテキスト) -
@inputs.<name>: アクションの入力(プロシージャコンテキスト) -
@utils.<utility>: ユーティリティ関数 (エスカレーション、トピック遷移、変数セット等)
よくあるパターン
シンプルなQ&Aエージェント
start_agent から直接メインのトピックへ飛ばし、対応を完結させるパターン。
config:
agent_name: "Simple_QA"
system:
messages:
welcome: "Hello! How can I help you today?"
error: "Sorry, something went wrong."
instructions: "You are a helpful assistant. Answer questions clearly."
start_agent topic_selector:
description: "Entry point"
reasoning:
actions:
start: @utils.transition to @topic.main
topic main:
description: "Answer user questions"
reasoning:
instructions:->
| Help the user with their questions.
遷移を伴うマルチトピック
start_agent でユーザーの意図に応じて適切なトピックへ振り分けるパターン。各トピック間でも相互に遷移可能。
start_agent topic_selector:
description: "Route to appropriate topic"
reasoning:
actions:
go_sales: @utils.transition to @topic.sales
description: "Handle sales inquiries"
go_support: @utils.transition to @topic.support
description: "Handle support issues"
topic sales:
description: "Handle sales"
reasoning:
instructions:->
| Help the customer with purchasing.
actions:
need_support: @utils.transition to @topic.support
description: "Transfer to support"
topic support:
description: "Handle support"
reasoning:
instructions:->
| Help resolve the customer's issue.
actions:
need_sales: @utils.transition to @topic.sales
description: "Transfer to sales"
状態管理を伴うアクション
アクション実行して外部からデータ取得したものを変数にセット。その値の有無で会話を制御するパターン。
variables:
customer_id: mutable string = ""
customer_name: mutable string = ""
customer_loaded: mutable boolean = False
topic customer_service:
description: "Customer service with data loading"
actions:
fetch_customer:
description: "Get customer details"
inputs:
id: string
outputs:
name: string
email: string
target: "flow://FetchCustomer"
reasoning:
instructions:->
if @variables.customer_id and not @variables.customer_loaded:
run @actions.fetch_customer
with id=@variables.customer_id
set @variables.customer_name = @outputs.name
set @variables.customer_loaded = True
if @variables.customer_name:
| Hello, {!@variables.customer_name}!
else:
| Please provide your customer ID.
よくある間違い
遷移構文の間違い
# ❌️ reasoning.actions では使用できない
go_next: transition to @topic.next
# 🟢 reasoning.actions
go_next: @utils.transition to @topic.next
# 🟢 ディレクティブブロック
after_reasoning:
transition to @topic.next
mutable変数のデフォルト値忘れ
# ❌️ デフォルト値がセットされていない
count: mutable number
# 🟢
count: mutable number = 0
Boolean値での小文字
# ❌️ true/falseは使用できない
enabled: mutable boolean = true
# 🟢
enabled: mutable boolean = True
... の間違った使用
# ❌️ - 変数の定義ではスロットフィリングは使用できない
my_var: mutable string = ...
# 🟢
my_var: mutable string = ""
linked 変数でのリスト型
# ❌️ - linked 変数はリスト型は使用できない
items: linked list[string]
# 🟢
items: mutable list[string] = []
linked 変数のデフォルト値
# ❌️ - linked変数はソースから値が渡されるので、デフォルト値はセットできない
session_id: linked string = ""
source: @session.sessionID
# 🟢
session_id: linked string
source: @session.sessionID
@utils関数のポストアクション
# ❌️ - utilities はポストアクションをサポートしていない
go_next: @utils.transition to @topic.next
set @variables.navigated = True
# 🟢 - @actions のみがポストアクションをサポート
process: @actions.process_order
set @variables.result = @outputs.result
参考
ローカル環境でAgent Scriptを試す手順を以下で確認できます。合わせて参照ください。