フローをストーリーラインにコンパイルする
複数ステップのプロセスを状態保持型有向グラフに変換し、作成、検証、公開を行います。
create_storylinevalidate_storylinepublish_storylinelist_storylinesupdate_storylineストーリーライン (Storyline) はエージェントに紐付いた有向グラフです。これは「1つの質問に答える」ことを「タスクを最初から最後まで遂行する」(情報収集、チューターリング、コーチングなど)に変換します。ノードはステップ(それぞれ独自のタスク/スキル/KB/ツール + 書き込み可能なプロファイル次元)です。出口には条件があります(ai / user_choice / rule / callback / goto_storyline)。ランタイムはエージェントの核や安全境界を編集しません — 最初のノードから最後のノードまで一定であり、これは規制対象または子供向け製品にまさに必要な性質です。
下書きを作成する
create_storyline(
agent_name="Support", key="loan-intake", name="Loan intake",
profile_schema={"docs_ready": {"type": "bool"}}, # dims that accumulate across nodes
graph={"nodes": [
{"node_key": "n1", "title": "Understand need", "flags": {"is_entry": True},
"on_enter_opening": "Hi — which kind of loan are you applying for?",
"exits": [{"kind": "ai", "label": "need clear", "to_node_key": "n2",
"ai_criteria": "the user stated the loan type and rough amount"}]},
{"node_key": "n2", "title": "Collect documents",
"task": "Collect the checklist items; chase missing ones across turns.",
"exits": [{"kind": "user_choice", "label": "documents ready", "to_node_key": "n3",
"user_choice": {"button_text": "I've uploaded everything"},
"writes": [{"ref": "dim", "key": "docs_ready", "op": "set", "value": True}]}]},
{"node_key": "n3", "title": "Hand off", "task": "Summarise the case and hand off to a human.",
"flags": {"is_terminal": True}, "exits": []}
]},
allow_agent_enroll=True,
enroll_trigger="the visitor says they want to apply for a loan",
)★ 検証し、公開する ★
validate_storyline(storyline_id="…") # → {"ok": true} is required to publish
publish_storyline(storyline_id="…") # freezes an immutable version and goes liveエンロール — 誰が、いつ入ってくるか(すべて公開が必要)
is_default=True— エージェントごとに1つ;最初の会話で自動エンロール。allow_agent_enroll=True+enroll_trigger— エージェントがトリガーを判断したときにユーザーをエンロールする。entry="user"(または"both") — フローはチャットウィジェットのガイド付きフローメニューと新規チャットドロップダウンに表示され、ユーザーが意図的に開始する(ボタンの押下であり、モデルの判断ではない)。display_nameと1行のdescriptionを付与する — これがメニューに表示される内容である。concurrency="session"と組み合わせて、「1会話につき1ケース」のフローにする:各選択は新しいケースを開く。- コンソールでの手動割り当て。
ユーザーに見えるもの — 可視性、バナー、および読み取り専用マップ
user_visibility は実行中のフローのエンドユーザー表示を制御します(デフォルト invisible):
invisible— UIなし;フローは静かに駆動する(以前の動作)。named— チャットの上にスリムなバナーが表示され、フローの名前が示される。それ以外は何もない。trail— バナー + View ボタンで読み取り専用マップを開く:すでに踏んだステップにはタイトルが表示され、踏んでいない分岐や将来のステップは匿名の灰色ブロックとして表示される(サーバー側で伏字処理 — ユーザーはフローの長さしか見えず、中身は見えない)。full— ステップx / yとフルマップ付きのバナー:すべてのステップに名前があり、完了済み/現在/今後のステップごとに色分けされる。
追加機能:allow_exit=True はバナーに終了ボタンを追加する(終了したフローはその会話で自動的には再エンロールされない;ユーザーが選択したフローはメニューから再入力可能で、進行状況は保持される)。show_profile=True はマップの下にプロファイル次元の現在値を一覧表示する(スキーマで min/max が宣言されている場合、数値はプログレスバーとして表示される)。ノードごとに、rewind: "reset" | "keep" を設定すると、ユーザーはフルマップで踏んだステップをクリックして戻ることができる — reset は到着時に撮影されたプロファイルスナップショットを復元し、keep は収集されたデータを保持する(学習/レビューフロー用)。現実世界の影響(記録の提出、書類の送信)は決してロールバックされないため、副作用のないステップのみをマークすること。IMチャネル(Telegram/WhatsApp)では、/storyline コマンドが現在のフローを報告し、trail/full の場合、同じ読み取り専用マップへの短期有効な署名付きリンクを返す。
レガシーな learner_visibility パラメータ名とその hidden / completed_only 値は依然として受け入れられる(これらは invisible / trail にマッピングされる)が、非推奨である — user_visibility を使用すること。
同時実行 — 進行状況は個人に追従するか、それともケースに追従するか?
concurrency は、このラインで1人のユーザーが持つことができる実行数を決定する:
"user"(デフォルト)— 1人につき1実行;すべての会話が同じ進行状況を継続する。カリキュラム、オンボーディング、KYC に適している:「この人 はどこまで進んだか」。"session"— 1会話につき1実行;新しいチャットは新しく独立したケースを開始する。免許申請、サポートチケット、製品ごとのフローに適している:「このケース はどこまで進んだか」。同じユーザーが3つのチャットで3つの製品申請を実行でき、それぞれが独自の進行状況とブラックボードを持つ。
状態を適切な場所に配置する:ケースの状態はブラックボードに(実行とともに生き死にする — 製品名、この申請の書類リスト)、個人に関する事実はプロファイル次元に(実行やストーリーラインを超えてユーザーに追従する — 会社詳細、検証済みアイデンティティ)。1会話につき1ケースは意図的な設計である:別のケースを開くには、別のチャットを開く。
concurrency を変更すると、将来のエンロールメントにのみ影響する;すでに実行中の実行はキーを保持する。
チェックリスト、ゲート付き選択、ファイル、および決定論的アクション
4つのノードレベルの機能により、「AI が完了時期を判断する」ことが蓄積された決定論的状态に変換される:
checklist— ノード上の[{key, label}, …]。各ターンでプラットフォームは、訪問者が実際に提供したもの(アップロード、または具体的な詳細を含む説明 — 約束はカウントされない)から項目にチェックを入れ、出口ルール{"op": ">=", "left": {"ref": "checklist"}, "right": {"value": 1}}によりすべてがチェックされた瞬間に進行する。読み取り専用マップでは、ユーザーにライブの ✓/○ リストが表示される。これは申請/承認フローに適した形状である:ステップ1で必要なものを告知し、ステップ2のチェックリストで項目ごとに収集する。choices_offer: "on_ready"— 選択ボタンのゲーム風ペース配分:ステップが完了するまで(チェックリスト完了、または提供したchoices_ready_criteriaが真と判断されるまで)、これらは非表示のまま(かつテキストマッチは無効 — ボタンの単語を入力して先送りすることはできない)。代替案間の本格的な意思決定にはuser_choiceを使用すること;単独の「続ける」ボタンは懸念材料である。{"ref": "files"}出口ルール内 — このノードにいる間にアップロードされたファイル/画像の数(遷移時にリセット)。files >= 2は完全に決定論的な「書類受信」ゲートである。questions— ノードごとのアイスブレイクチップ(最大6個):ユーザーがこのステップにいる間に尋ねる可能性が高い質問で、その間に表示されるタップ可能な提案として表示される。on_enter_openingと組み合わせて、各ステップが自己紹介を行い、入り口を提供するようにする — ユーザーは「ここで何をすべきか」を悩むべきではない。on_enter_actions/on_complete_actions—[{tool, args}]プラットフォームは、ステップに入ったとき/フローが完了したときに決定論的に実行する(例:終端ステップでmcp__agent4__submit_leadを使用してリードを提出)。文字列引数は中括弧テンプレートで次元とブラックボードキーを補間する。失敗はログに記録され、チャットを壊すことはない。
ストーリーラインがどれだけ長くても、コンテキストは平坦である:各ターンでは、現在のノード(タスク、リソース、選択)、プロファイル次元、サイズ制限付きのブラックボードのみが注入され、グラフ全体や過去のステップは注入されない。長い旅路(1年間、シーズン全体のゲームアーチなど)は連鎖するストーリーライン(on_complete: goto_next)として構成すべきである:各ラインのブラックボードは新規開始され、プロファイル次元は継続される。これはまさに「過去を要約し、現在をそのまま保持する」である。
出口の判断者は、最後のメッセージだけでなく、直近の会話ウィンドウと収集された状態を見る — ただし、ai_criteria は訪問者が言ったことまたは行ったことに限定すること。上記のチェックリストメカニズムは、文章による基準よりも依然として強力である。
デザインの落とし穴 — これらそれぞれが生産環境で停止したフローを引き起こした
あなた(このエージェントを構築する者)がこれらのバグの最も可能性の高い著者です。公開する前にすべてを確認してください:
rule出口には書き込み手が必要である。readiness >= 100は、実際にreadinessを書き込むものがなければ行き止まりである:出口のwrites(決定論的 — 推奨)、ノードのprofile_writes(source: "ai"で会話からスコアリング)、別のストーリーライン、または手動のコンソール編集。validate_storylineはこれをwarn.rule_unwritten_dimとしてフラグを立てる — 外部の書き込み手が存在することがわかっている場合を除き、この警告をバグとして扱うこと。この正確なミスが1回出荷された:2番目のステップが何も書き込まない次元にゲートされた3ステップのインテーク。ユーザーはそれを通過できなかった。- AIスコアリングされた次元は正確な境界に到達することはほぼない。 次元がモデルによってスコアリングされる場合、
>= 100(または== max)は実際には発火しない — モデルは保守的にスコアリングする。現実的な閾値(>= 70)でゲートするか、ステップの完了をuser_choiceにし、出口のwritesを使用して値を決定論的に設定する。 user_choiceはボタンのテキストと正確に一致する — ラベルはそれが何をするかを示さなければならない。 訪問者のメッセージはbutton_textと等しくなければならない。表示されるラインでは、ウィジェットはこれらを実際のボタンとしてレンダリングするので、完全で正確な動詞句を書くこと — 「開始」ではなく「書類収集を開始」(何を開始するか? — テストからの実際のフィードバック)。それらを区別し、聴衆の言語で記述すること。invisibleラインにはボタンがない — ノードtaskにオプションを再述すること。本格的な意思決定(どの分岐、送信 vs 編集継続)にはuser_choiceを優先すること;「このステップで完了したか」は AI/ルール出口の役割であり、ボタンの役割ではない。- 公開はすでに実行中の実行に触れない。 エンロールメントは開始時のリビジョンに固定される — バグ修正リリースは新しい実行にのみ到達する。既存のユーザーを移動するには、
POST /storylines/{id}/enrollments/migrateを呼び出す(resetでエントリーに戻すか、moveでノードに移動する — どちらも実行を現在の公開リビジョンに再固定する)。 - 配布する前にユーザーとしてラインを歩く。 シェアの
/s/ページを開き、フローに入り、すべてのボタンと分岐をクリックして終了まで進む。エディタのテスト実行はグラフをシミュレートするが、実際のページのみがオープニング、ボタン、可視性、完了を一緒に実行する。
出口は優先度順(リスト順)に評価される:決定論的な rule / user_choice / callback が最初に評価され、ai が最後である。if/else、リトライループ、AND-ジョインを決定論的な出口から構築すること — LLM に賭けない。update_storyline(PUT セマンティクス;出口と漏斗が参照する node_key を安定して保持)で下書きを編集する。
報告を返す。 公開されたストーリーラインのコンソールリンク —
https://console.agent4.io/#/storylines/<id>(create_storylineからの id)— と、フローの要約およびユーザーの入り方を1行で返す。