馬戲團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 的觸發時機:被動介入,不是每輪都出手

  1. Actor 丟球明確 → GM 不介入
  2. Actor 丟球空白 / 開放問題 → GM 出手判斷誰接最自然
  3. 某 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 出手:

  1. <cue> 空白:actor 沒指定接球者
  2. <cue> = ANY(開放問題):例如「有誰知道昨晚發生了什麼?」
  3. 冷落保護:某 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 下一步:指令介面與實作

本份文件定版的是理論基礎與架構邏輯。接下來要定版的是:

  1. 導演指令介面:SETUP / RUN / CUE / CUT / NOTE / RESUME / REPLAY 的確切語法與語義
  2. circus.py 核心函式簽名setup_scenerun_roundcuecutbranch_from
  3. 最小可行實作:能跑一場 3 角色、5 輪的 demo

附錄 A:名詞對照

中文英文本系統角色
導演Director使用者(人)
舞台監督Stage Manager / GM受限的 LLM agent
演員Actor完整的 LLM agent
前台Frontstage公開 transcript
後台Backstage私有 thought 歷史
靈魂Soulactor 的靜態認知封包
場次Scene一整個獨立的排演情境
排演Take同一場次的一次完整跑演
丟球Cue發言權指向下一位
導戲筆記Direction開演前對演員的交代
私人耳語Whisper演出中對特定 actor 的即時指示