Cookbook
Storylines · for AI agents

將流程編譯為故事線

將多步驟流程轉換為有狀態的有向圖 — 建立、驗證、發布。

MCP tools:create_storylinevalidate_storylinepublish_storylinelist_storylinesupdate_storyline

Storyline 是一個掛載在 agent 上的有向圖:它將「回答一個問題」轉變為「端到端執行整個任務」(收集資料、輔導、教練……)。節點是步驟(每個步驟都有各自的任務 / 技能 / 知識庫 / 工具,以及可寫入的個人資料維度);出口帶有條件(ai / user_choice / rule / callback / goto_storyline)。執行階段絕不會編輯 agent 的核心或安全邊界——它從第一個節點到最後一個節點保持不變,這正是受監管產品或兒童導向產品所需要的。

建立草稿

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 — 每個 agent 一個;在第一次對話時自動入會。
  • allow_agent_enroll=True + enroll_trigger — 當 agent 判斷觸發條件滿足時,由 agent 將用戶入會。
  • entry="user"(或 "both") — 流程會顯示在聊天小工具的引導流程選單和「新對話」下拉選單中,因此由用戶有意識地啟動(是一個按鈕,而非模型判斷)。提供 display_name 和一行 description —— 這就是選單顯示的內容。搭配 concurrency="session" 用於「每次對話一個案例」的流程:每次選擇都會開啟一個新案例。
  • 在控制台中手動指派。

用戶所見 — 可見性、橫幅和唯讀地圖

user_visibility 控制運行中流程的終端用戶呈現(預設為 invisible):

  • invisible — 沒有任何 UI;流程靜默驅動(先前行為)。
  • named — 聊天上方顯示一個簡短的橫幅,展示流程名稱。除此之外沒有其他內容。
  • trail — 橫幅 + 一個View按鈕,開啟唯讀地圖:已執行的步驟顯示其標題;未執行的分支和未來步驟為匿名灰色區塊(服務端隱藏 — 用戶僅能看到流程的長度,而非其中的內容)。
  • full — 帶有步驟 x / y 的橫幅 + 完整地圖:每個步驟都有名稱,並用顏色區分已完成 / 當前 / 即將進行。

額外功能:allow_exit=True 在橫幅中添加一個退出按鈕(已退出的流程在該對話中不會自動重新入會;用戶選擇的流程可以從選單重新進入,進度保留)。show_profile=True 在地圖下方列出個人資料維度的當前值(當 schema 宣告了 min/max 時,數字以進度條顯示)。針對節點rewind: "reset" | "keep" 允許用戶在完整地圖中點擊已執行的步驟並返回 — reset 恢復進入時拍攝的個人資料快照,keep 保留收集的數據(學習/審查流程)。實際世界的副作用(已歸檔的記錄、已提交的文件)絕不會回滾,因此僅標記無副作用的步驟。在 IM 頻道(Telegram/WhatsApp)上,/storyline 命令會報告當前流程,並對於 trail/full 返回一個短壽命的簽名鏈接,指向相同的唯讀地圖。

舊版 learner_visibility 參數名稱及其 hidden / completed_only 值仍被接受(它們分別映射到 invisible / trail),但已棄用 — 請使用 user_visibility

併發 — 進度是跟隨個人,還是跟隨案例?

concurrency 決定一個用戶在此線上可以擁有多少個運行實例:

  • "user"(預設)— 每人一個運行實例;每次對話都繼續相同的進度。適合課程、入職培訓、KYC:「這位用戶進展到哪一步了」。
  • "session"每次對話一個運行實例;新對話開始一個全新的、獨立的案例。適合執照申請、支援工單、每個產品的流程:「這個案例進展到哪一步了」。同一用戶可以在三個不同的對話中運行三個產品申請,每個申請都有各自的進度和黑板。

將狀態放在正確的位置:案例狀態在黑板上(它隨運行實例而生滅 — 產品名稱、此申請的文件列表),關於用戶的事實位於個人資料維度中(它們跟隨用戶跨運行實例和 storyline 流動 — 公司詳細資訊、已驗證的身份)。每次對話一個案例是故意的:要開啟另一個案例,請開啟另一個對話。更改 concurrency 僅影響未來的入會;已在進行中的運行實例保留其鍵。

檢查表、閘道式選擇、文件和確定性動作

四個節點級別的功能將「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 歸檔客戶)。字符串參數使用大括號模板插值維度和黑板鍵。失敗會被記錄,且絕不會破壞對話。

無論 storyline 多長,上下文保持扁平:每次對話僅注入當前節點(任務、資源、選擇)、個人資料維度和一個大小受限的黑板 — 絕不注入整個圖或過去步驟。長途旅程(一學年、一整個遊戲賽季)應該鏈接 storyline(on_complete: goto_next):每條線的黑板從頭開始,而個人資料維度會保留,這正是「總結過去,原樣保留現在」。

出口裁判現在可以看到最近對話窗口和收集的狀態,而不僅僅是最後一條消息 — 但請保持 ai_criteria 關於訪客的事情;上述檢查表機制仍然比任何文本標準更強大。

設計陷阱 — 這些都會導致生產環境中流程卡住

你(構建此 agent 的人)是這些錯誤最可能的作者。在發布前檢查每一項:

  1. rule 出口需要一個寫入器。 readiness >= 100 是一個死胡同,除非實際上有人寫入了 readiness:出口的 writes(確定性 — 首選)、節點的 profile_writes(來源為 ai,從對話中評分)、另一個 storyline,或手動控制台編輯。validate_storyline 現在將此標記為 warn.rule_unwritten_dim — 除非你知道存在外部寫入器,否則將此警告視為錯誤。這個確切的錯誤曾導致一次發布:一個三步收集流程,其第二步閘道於一個沒有任何寫入器的維度;用戶永遠無法通過。
  2. AI 評分的維度幾乎從不達到精確邊界。 如果維度由模型評分,>= 100(或 == max)實際上不會觸發 — 模型評分保守。閘道於一個現實的閾值(>= 70),或使步驟完成成為 user_choice 並使用出口的 writes 確定性地設置值。
  3. user_choice 精確匹配按鈕文本 — 且標籤必須說明其作用。 訪客的消息必須等於 button_text。在可見線上,小工具將這些渲染為真實按鈕,因此請撰寫完整、精確的動詞短語 — 「開始文件收集」,而不是「開始」(開始什麼? — 來自測試的真實反饋)。保持它們獨特且符合受眾語言。在 invisible 線上沒有按鈕 — 在節點 task 中重述選項。對於真正的決策(哪個分支、提交 vs 繼續編輯)優先使用 user_choice;「我是否完成了此步驟」是 AI/規則出口的工作,而不是按鈕。
  4. 發布不會觸及已在進行中的運行實例。 入會固定在它們開始的修訂版上 — 錯誤修復發布僅影響運行實例。要移動現有用戶,請調用 POST /storylines/{id}/enrollments/migratereset 返回入口或 move 到節點 — 兩者都將運行實例重新固定到當前發布的修訂版)。
  5. 在交付之前,以用戶身份走一遍流程。 打開分享頁面的 /s/ 頁面,進入流程,點擊每個按鈕和分支直到結束。編輯器的測試運行模擬了圖;只有真實頁面會一起測試開場白、按鈕、可見性和完成情況。

出口是優先級排序的(列表順序):確定性 rule / user_choice / callback 優先判斷,ai 最後。從確定性出口構建 if/else、重試循環和 AND 連接 — 不要賭博 LLM。使用 update_storyline 編輯草稿(PUT 語義;保持所有 node_key 穩定,因為出口和漏斗引用它)。

回報。 返回已發布 Storyline 的控制台鏈接 — https://console.agent4.io/#/storylines/<id>(來自 create_storyline 的 id)— 並附上流程的一行摘要以及用戶如何進入它。