將流程編譯為故事線
將多步驟流程轉換為有狀態的有向圖 — 建立、驗證、發布。
create_storylinevalidate_storylinepublish_storylinelist_storylinesupdate_storylineStoryline 是一個掛載在 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 的人)是這些錯誤最可能的作者。在發布前檢查每一項:
rule出口需要一個寫入器。readiness >= 100是一個死胡同,除非實際上有人寫入了readiness:出口的writes(確定性 — 首選)、節點的profile_writes(來源為ai,從對話中評分)、另一個 storyline,或手動控制台編輯。validate_storyline現在將此標記為warn.rule_unwritten_dim— 除非你知道存在外部寫入器,否則將此警告視為錯誤。這個確切的錯誤曾導致一次發布:一個三步收集流程,其第二步閘道於一個沒有任何寫入器的維度;用戶永遠無法通過。- 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 穩定,因為出口和漏斗引用它)。
回報。 返回已發布 Storyline 的控制台鏈接 —
https://console.agent4.io/#/storylines/<id>(來自create_storyline的 id)— 並附上流程的一行摘要以及用戶如何進入它。