馬戲團Circus引用劇場的「即興劇場」概念,讓不同Agents飾演不同角色,成為編劇的排演沙盒。不是敘事作業系統,不是連續劇引擎。是讓編劇把同一場 5 分鐘的戲反覆排演、淘洗火花的實驗工具。

第一部分:理論基礎
一、核心哲學
1.1 創作者的退位
傳統 AI 劇作的困境是:單一 LLM 同時扮演所有角色,所有「衝突」其實都發自同一個腦袋。不管包裝得多精巧,它始終是一個作者在跟自己下棋——衝突流於表面,因為沒有真實的資訊不對稱。
馬戲團系統主張一個哲學上的退位:編劇不再是全知全能的神,而是劇場導演。導演不替演員寫台詞,導演設計「碰撞環境」,然後看角色自己演出來。看排演、給筆記、調整、重來。
這不是「AI 代筆」,這是一種新的創作思維。
1.2 捕捉 vs 生成
當角色真正住進創作者腦袋,話語是被捕捉下來的,不是被設計出來的。
馬戲團系統透過多個獨立 agent 的碰撞,模擬出這種「他者性」——讓對話在意外中湧現,而不是從一個集中的生成器產出。編劇的工作從「生成文字」切換為「設置情境、觀察湧現、挑選火花」。
1.3 為什麼叫「馬戲團」
馬戲團的本質是:各自獨立的 act 同台演出,互不干擾但共享觀眾。馴獸師、小丑、空中飛人各有各的劇本、各有各的動機、各有各的訓練,他們不需要知道對方的全部,只需要在同一個舞台上同時存在。
這正好對應本系統的根基——資訊不對稱 + 共享舞台。A 不知道 B 在隱瞞什麼,B 不知道 C 看見了什麼。每個演員帶著自己的私有設定進場,碰撞出的張力是真實的。
1.4 定位:排演沙盒
這個工具不追求讓 AI 寫完一整齣戲。它的真正使用場景是:
編劇想寫一場戲 → 設置場景與角色 → 讓 agents 排演 5 分鐘 → 看結果 → 編劇覺得「嫌犯太快鬆口了」→ 調整筆記 → 再排一次 → 從 take_3 裡抓出一句好台詞,寫進自己的劇本稿
核心迴圈是四步:
設置 → 排演 → 淘洗 → 調整再排
takes/ 資料夾是系統的核心,不是配角——真正的創作工作發生在「第一次排完之後的那個調整」。
二、限制與哲學陷阱(必須正視)
2.1 偽潛意識
Agent 內部沒有真正的痛苦累積。人物弧線的重量來自「記憶文字」,而非真實的情感生理反應。這是 LLM 本質的限制,系統無法消除,只能透過設計降低其影響(例如強化不可妥協的動機、混用不同模型)。
2.2 模型趨同性
同一個 LLM 扮演多個角色容易落入「理性、好言好語」的迴圈。解法:
- 強化每個角色「不可妥協的動機」與「內在矛盾」
- 混用不同模型(Claude + Gemini + Ollama 擔任不同角色)
- 導演透過私語打破趨同的僵局
2.3 失控的缺席
AI 不會被自己的無意識背叛——它沒有真正的「自我驚訝」。那個讓戲劇活起來的「神來之筆」,仍然需要導演的眼光從機率擾動中識別出來。這個工具不能取代導演的判斷力,它只是放大導演能觀察到的可能性空間。
第二部分:架構邏輯
三、三層 Agent 架構
整個系統由三個角色組成,權責清晰不重疊:
| 角色 | 身份 | Context 權限 | 職責 |
|---|---|---|---|
| Director | 人 | 全視野(含所有 backstage) | 設置場景、下指令、看結果、調整、決定 |
| Stage Manager (GM) | 受限 Agent | 只有公開資訊 | 接球語義判斷、兜底、執行導演指令 |
| Actors | 完整 Agent | 自己的私有 + 全部公開 | 演戲、向下一位丟球 |
3.1 Director(人)
導演是真正的創作者,擁有終極控制權。導演:
- 設置場景、撰寫角色 soul.md、下導戲筆記
- 隨時可以喊 CUT 中止演出
- 用 CUE 點名下一位發言者、指定動作
- 事後看 transcript(前台)與 backstage(後台)做判斷
- 決定哪一個 take 值得保留、哪裡要重來
3.2 Stage Manager(受限 Agent)
GM 的角色借自真實劇場的舞台監督——懂戲的節奏,能做語義判斷,但不改寫劇本也不演戲。
GM 是一個 LLM agent(不是規則引擎),因為「這句話該由誰接」是語義判斷而不是數值運算。但它的 context 嚴格受限:
GM 能看見:
transcript.md(公開前台紀錄)context.md(場景設定)- 在場角色名單
- 每個角色的「最近發言輪次」計數
GM 絕對不能看見:
- 任何 actor 的
soul.md或後台獨白 director_notes.md的私人段落- 任何
<thought>內容
這個邊界是根基——GM 必須只憑「觀眾看得到的資訊」做判斷,才不會污染資訊不對稱。
GM 的觸發時機:被動介入,不是每輪都出手
- Actor 丟球明確 → GM 不介入
- Actor 丟球空白 / 開放問題 → GM 出手判斷誰接最自然
- 某 actor 連續 N 輪沒發言 → GM 下一輪給他機會
GM 的決策過程不寫進 transcript(那是內部調度,不是舞台上發生的事)。
3.3 Actors(完整 Agent)
演員是主角。每個 actor 有完整的私有靈魂 + 公開視野 + 自己的後台獨白歷史。每次被點名發言時:
讀入 → 思考 → 輸出 <thought> + <action> + <dialogue> + <cue>
四、雙軸設計:星狀運算 × 網狀認知
這兩個看似矛盾的結構其實是兩個維度,並存:
4.1 星狀運算架構
每次 agent 呼叫都是 stateless 的。GM 是唯一的樞紐,由它組裝 prompt、分派呼叫、寫入檔案。Actor 之間不直接通訊,所有互動透過共享的 transcript 發生。這保證了 context 的乾淨,防止橫向資料污染。
4.2 網狀認知結構
雖然運算架構是星狀,但每個 actor 對其他人都有私有的解讀、偏見、懷疑、信任。這些東西不透過集中式的信任矩陣管理,而是活在每個 actor 自己的後台獨白歷史裡——A 的 backstage.log 記錄著他對 B、對 C 的逐步觀察與判斷。這就是「網」。
運算走中央,認知走分散。這是整個架構的雙軸。
五、資訊三層與可見性矩陣
系統中的所有資訊嚴格歸類為三層:
| 層 | 內容 | 誰看得到 | 儲存位置 |
|---|---|---|---|
| 前台 | 公開事件(台詞、動作、cue) | 所有 actor + GM + 導演 | transcript.md |
| 後台 | 內心獨白(thought) | 該 actor 自己 + 導演 | backstage/{name}.log |
| 靜態靈魂 | 角色小傳 + 前期劇本 + 導戲筆記 | 該 actor 自己 + 導演 | actors/{name}/soul.md |
可見性原則:
- 其他 actor 看不到別人的後台或靈魂(資訊不對稱的根基)
- GM 只能看前台與場景設定(維持它的分寸)
- 導演全視野(創作者的特權)
沒有第四類曖昧資訊層。早期版本提過的「記憶沉澱 memory.md」與「情感帳本 ledger.json」都已被廢棄——前者冗餘(後台獨白歷史已自然承接),後者是遊戲化思維遺跡(見第十一節反模式)。
六、soul.md 的三段式
Soul.md 不是靜態不變的檔,而是每場戲開始前、由導演重新組裝的動態認知封包。它對應真實劇場排練的邏輯:每場演出前,導演會跟每個演員對一次戲。
soul.md 包含三段:
6.1 角色小傳(穩定)
演員的人物功課。包含:
- 背景、性格、說話癖好
- 核心動機
- 不可洩漏的秘密
- 不可妥協的底線
除非角色經歷重大事件,這段基本上不變。
6.2 前期劇本(每場更新,角色視角)
這場戲開始前,這個角色所知道的前情脈絡。
關鍵:這不是全知視角的劇情摘要,是該角色所知道的那一份。
舉例:
- scene_005 林小姐親眼看見刑警收賄
- 林小姐的前期劇本要寫進這件事
- 但刑警的前期劇本絕不能寫「林小姐看到了」
如果導演偷懶直接貼完整前情給每個角色,資訊不對稱瞬間崩盤。
輔助機制:提供一個 summarize_for(character, full_history) 函式,導演只需寫一份完整前情,由 LLM 幫每個角色各自篩出他知道的那部分。
6.3 導戲筆記(每場重寫)
開演前導演跟演員對的戲。這不是「目標」一個欄位,而是一段開放的備忘,可以包含:
- 你想要什麼(objective)
- 你現在的內在狀態(痛苦、渴望、恐懼、困惑)
- 你進場時的情緒起點
- 你跟場上某人的關係暗流
- 任何導演想讓演員帶進場的東西
即興劇場的核心原則:給目標不給方法。
LLM 有一個天性:一旦給它步驟,它就會照步驟演。因此導戲筆記必須嚴守「說該說的、不越界到怎麼做」的分寸:
- ✓ 好:「你的目標:讓嫌犯在 20 分鐘內承認 11 點他不在家。但不能讓他感覺受逼迫。」
- ✗ 壞:「你先威脅他,看他反應軟化,然後提出不在場證明的疑點,最後開價交換。」
後者是在寫劇本不是導戲。一旦這樣寫,這個 agent 的表演會變得機械化,碰撞意外的可能性也被殺掉。
進階技巧:寫「對立動機」而不是單一目標
目標:讓嫌犯承認 11 點不在家 內在矛盾:但你其實懷疑他是被上司逼的,你不想真的毀了他
「想要但又不想」的張力才是戲劇動力的來源。
七、雙模式運作
導演對場上的介入程度分為兩種模式,可以在同一場戲之間切換:
7.1 RUN 模式(放手觀察)
導演預設開場者,按 RUN [N] 讓場子自己跑 N 輪。
- 發言權透過 actor 之間的
<cue>丟球傳遞 - GM 只在球沒有明確接應者時兜底
- 導演只看、不打斷
- 用於:初排、探索、讓意外發生
7.2 CUE 模式(逐句導戲)
每一句都由導演點名:
@林小姐 說 → agent 產出下一句
@刑警 動作:拍桌子 → agent 產出動作描述
用於:精修、抓細節、控節奏。
實務上:前幾輪用 RUN 放手看,抓到火花就 CUT,再用 CUE 逐句精修。
八、丟球機制(RUN 模式下的核心)
8.1 主旋律:演員之間自己丟球
真實對話本來就有指向性。林小姐說「張律師,你覺得呢?」——這句話本身決定了下一個該誰說。
每個 actor 的輸出包含一個 <cue> 欄位,明確指向下一位發言者:
<thought>私下的想法</thought>
<action>林小姐靠向椅背,刻意看向律師</action>
<dialogue>「張律師,你覺得呢?」</dialogue>
<cue>律師</cue><cue> 是前台動作的延伸(看誰、對誰說話),寫進 transcript。「誰接話」本身就成為表演的一部分——agent 選擇看誰、忽視誰、挑戰誰,這些選擇都是戲劇動作。
8.2 GM 兜底(被動介入)
三種情況 GM 出手:
<cue>空白:actor 沒指定接球者<cue>= ANY(開放問題):例如「有誰知道昨晚發生了什麼?」- 冷落保護:某 actor 連續 N 輪(預設 3)沒發言,GM 下一輪給他機會,prompt 附加「你已經沉默很久了,可以選擇說話或繼續保持沉默」
GM 只憑公開資訊做判斷,決策不寫進 transcript。
8.3 沉默也是動作
被點到的 actor 不一定要講話,可以用 <action> 代替 <dialogue>:
<action>沉默地搖頭</action>
<cue>刑警</cue>這保留「冷場」、「欲言又止」這些劇場裡最珍貴的時刻。
8.4 導演的最終安全閥
不管 RUN 走得多偏、GM 判斷多奇怪,導演隨時可以:
CUT → CUE @林小姐 從「你那晚到底在哪」接話
戲立刻回到導演手上。系統有最後的兜底。
九、發言輸出格式(定版)
每次 actor 發言的標準 XML 結構:
<thought>
(後台獨白,可多行。僅該 actor 自己與導演可見。
追加到 backstage/{name}.log)
</thought>
<action>
(前台動作描述。所有人可見。追加到 transcript.md)
</action>
<dialogue>
(前台台詞。所有人可見。追加到 transcript.md)
</dialogue>
<cue>
(下一位發言者名字,或 ANY,或空白。
寫進 transcript.md 作為 action 的延伸)
</cue>規則:
<thought>必填(就算只是一句感受)<action>與<dialogue>至少要有一個(兩個都有也可以)<cue>必填,可為 ANY
十、檔案結構(定版)
scenes/
scene_003/
context.md # 舞台公知(時空、物理邊界、外部壓力)
director_notes.md # 演出中導演的即時耳語(含全場/私人)
transcript.md # 前台公開紀錄
backstage/
林小姐.log # 林小姐歷來所有的 <thought>
刑警.log
律師.log
actors/
林小姐/
soul.md # 小傳 + 前期劇本 + 導戲筆記
刑警/
soul.md
律師/
soul.md
takes/
take_1/ # 一次完整排演的快照(整個 scene_003 資料夾複製)
take_2/
take_3/
設計要點:
- 每個 actor 只有一個 soul.md,沒有 memory.md、沒有 ledger.json
- backstage 是每個 actor 各一個 log 檔,不互相可見
- takes 是整個場景資料夾的快照,可以隨時回溯任一版本
儲存哲學:MD 優先 + 檔案即狀態
- 不使用資料庫。每個檔案都可以用 Obsidian 直接打開編輯。
- 整個場景資料夾就像一本導演筆記本,可翻頁、可分頁、可撕下重寫。
十一、Prompt 組裝公式(定版)
輪到林小姐發言時,組進 prompt 的是:
[林小姐/soul.md] ← 小傳 + 前期 + 導戲筆記
[context.md] ← 舞台公知
[transcript.md] ← 本場前台全部
[backstage/林小姐.log] ← 她自己過去所有的 thought
[director_notes.md 中給林小姐的段落] ← 導演即時私人耳語
+ 系統提示:輸出格式為 <thought>/<action>/<dialogue>/<cue>
↓
Agent 輸出
↓
<thought> → 追加到 backstage/林小姐.log
<action>/<dialogue>/<cue> → 追加到 transcript.md
Token 預算估算(每次 actor 呼叫):
- soul.md ~800
- context.md ~300
- transcript.md ~2000(5 分鐘的戲大約如此)
- backstage log ~1000
- director_notes 私人段 ~200
- 系統提示 ~200
- 總計 ~4500 tokens(輕量,即便 10 分鐘長的戲也不會爆)
十二、導演介入的四個深度
| 深度 | 手段 | 用途 |
|---|---|---|
| 即時微調 | 編輯 director_notes.md | 戲進行中下耳語(全場/私人) |
| 模式切換 | CUT → CUE → RESUME | 把自由排演轉成逐句導戲 |
| Take 分叉 | 複製整個 scene 資料夾為 take_N | 帶著修訂的初始狀態重排 |
| 靈魂調校 | 編輯 actor/{name}/soul.md | 修改角色的小傳、前情、導戲筆記 |
十三、反模式(為什麼不做那些事)
廢棄決策集錦——記錄每一個被排除的設計,避免未來不小心走回老路。
13.1 不做情感數值化
早期版本設計過 ledger.json 存「憤怒值 0.8、信任度 0.2」這類數值。廢棄理由:
- 源自狼人殺/RPG 的遊戲化思維,不適合即興劇場的多樣性
- 「羞愧到不敢抬頭」、「想認錯又拉不下臉」這類真正的心理層次,本來就無法量化
- 一旦量化,agent 會往數值演而不是往真實心理演
角色的成長改由敘事性承擔(backstage 的獨白歷史)。
13.2 不做記憶沉澱
早期版本設計過每輪結束後由 GM 問 agent「你要更新什麼到私人記憶?」。廢棄理由:
- 強迫 agent 跳出角色做元認知,違背即興劇場精神
- 冗餘——actor 下一輪讀 transcript + 自己的 backstage log 就已經承接了連續狀態
- 製造了一個前台/後台二分法之外的曖昧第三類
廢棄後 agent 永遠在角色裡面,從不自我整理。
13.3 GM 不做戲劇判斷
早期版本設計過「憤怒值 > 0.8 自動搶戲」之類的自動觸發機制。廢棄理由:
- 把最核心的導演工作外包給規則引擎
- 真實劇場裡節奏永遠由人控制
- 違背「創作者(人)是真正節奏控制者」的哲學
GM 只做語義上的接球判斷(誰接最自然),不做戲劇節奏判斷(誰該情緒爆發)。
13.4 不做「搶戲模式」
早期版本設計過 agent 自評「說話慾望」然後由 GM 挑分數最高的。廢棄理由:
- 跟 13.3 同源——把戲劇判斷外包給演算法
- 同款 LLM 的意願分數會趨同,所有 agent 都說自己「7 分想講」
- 讓 agent 每輪做元認知,違背角色沉浸
取而代之的是「演員自己丟球 + GM 兜底 + 導演安全閥」三層結構。
十四、開放問題與後續
14.1 跨場景延續(選配功能)
這個工具的核心定位是 5 分鐘的排演沙盒,不是連續劇引擎。但如果編劇真的要寫連續劇,機制已經內建:
- 每場戲結束後,導演手動更新下一場的 soul.md
- 第 2 部分(前期劇本)寫入這個角色從前場帶過來的記憶
- 第 3 部分(導戲筆記)重寫本場專屬
- backstage.log 不跨場延續(場場重置或另存)
這個「吸收與重寫」的動作由人做,不由 agent 自動做。
14.2 模型異質性(建議配置)
為了對抗模型趨同性,建議:
- 不同 actor 用不同模型(Claude / Gemini / Ollama 混用)
- GM 固定用一個模型,避免判斷風格漂移
- 導演自行選擇最適合本場的搭配
14.3 下一步:指令介面與實作
本份文件定版的是理論基礎與架構邏輯。接下來要定版的是:
- 導演指令介面:SETUP / RUN / CUE / CUT / NOTE / RESUME / REPLAY 的確切語法與語義
circus.py核心函式簽名:setup_scene、run_round、cue、cut、branch_from等- 最小可行實作:能跑一場 3 角色、5 輪的 demo
附錄 A:名詞對照
| 中文 | 英文 | 本系統角色 |
|---|---|---|
| 導演 | Director | 使用者(人) |
| 舞台監督 | Stage Manager / GM | 受限的 LLM agent |
| 演員 | Actor | 完整的 LLM agent |
| 前台 | Frontstage | 公開 transcript |
| 後台 | Backstage | 私有 thought 歷史 |
| 靈魂 | Soul | actor 的靜態認知封包 |
| 場次 | Scene | 一整個獨立的排演情境 |
| 排演 | Take | 同一場次的一次完整跑演 |
| 丟球 | Cue | 發言權指向下一位 |
| 導戲筆記 | Direction | 開演前對演員的交代 |
| 私人耳語 | Whisper | 演出中對特定 actor 的即時指示 |