🎯 什麼情境該想到我

當你「發現寫在最前面的指令,聊了幾十輪後 AI 就不理了,想把提醒插到靠近最新訊息的地方」的時候。

⚙️ 怎麼用

Author’s Note 是什麼:浮動提示

Author’s Note(AN,作者註)是一段不固定在 prompt 開頭、而是注入在聊天歷史特定深度的提示。它讓你不修改角色卡就能影響 AI 的行為,典型內容像:

  • 「場景轉換到夜晚」
  • 「增加描述細節」
  • 「讓角色表現得更警覺」

為什麼放在聊天歷史中間? 模型對離當前生成位置越近的內容關注度越高。系統提示放在最前面,聊天一長就被幾千 token 的對話隔開;AN 則永遠跟著聊天的尾巴走,距離生成點始終只差固定幾則訊息。

AN 的參數

參數例意義
prompt「增加描述細節」注入內容
depth4從聊天底部往上數第幾則的位置插入
interval1每幾則使用者訊息插入一次
position0 / 1 / 20 = 場景後、1 = 聊天中(in-chat)、2 = 場景前
role0 / 1 / 20 = system、1 = user、2 = assistant
allowWIScanfalse是否讓 World Info 掃描 AN 內容找關鍵詞

depth 怎麼數:depth=4 表示「AN 之後還有 4 則訊息」。以 7 則聊天為例:

Message 1 (最舊)
Message 2
Message 3
  ← AN 注入在這裡 (depth=4)
Message 4
Message 5
Message 6
Message 7 (最新)

depth=0 就是貼在最後一則訊息之後,最接近生成點、影響力最強也最容易「喧賓奪主」。

★ interval 的用意(推測):不必每輪都插,讓提示「間歇提醒」,減少模型把它當作對話內容而照抄的機會。
★ allowWIScan 預設關閉(推測理由):AN 常寫著劇情關鍵字,若讓 WI 掃它,可能每輪都觸發同一批設定條目。

角色專屬 AN 與全域 AN 的合成

每個角色可有自己的 AN,與全域 AN 的關係由 chara_note_position 決定:

值模式結果
0replace只用角色 AN,全域 AN 被忽略
1before角色 AN 在前、全域 AN 在後
2after全域 AN 在前、角色 AN 在後

例:全域 AN「增加描述細節」+ 角色 AN「Alice 總是用比喻說話」,選 before 時兩句都會出現,角色那句在上。

與 World Info 合成一個區塊

World Info 條目可以指定 position=ANTop(2) 或 ANBottom(3),與 AN 本體組成一個合成區塊:

[WI 條目 (position=ANTop)]      ← 在 AN 之上
[Author's Note 內容]             ← AN 本體
[WI 條目 (position=ANBottom)]   ← 在 AN 之下

★ 這讓 WI 的動態內容可以「搭便車」進入 AN 的高注意力位置——被關鍵詞觸發的設定,不必擠在 prompt 前段被遺忘。

Extension Prompts:通用注入框架

AN 其實只是 Extension Prompts 中的一種。Extension Prompts 是一個通用機制,讓各擴展以一個 key 註冊內容,並指定注入位置:

位置類型值說明使用情境
NONE-1不自動注入(outlet 模式)只供 {{outlet::key}} 讀取
IN_PROMPT0放在 prompt 區段中(scenario 前後)靜態的系統級指令
IN_CHAT1聊天歷史的特定深度(配 depth、role)動態上下文指引
BEFORE_PROMPT2整個 prompt 之前最高優先級指令

已知的 key:

Key來源用途典型位置
1_memorySummarize聊天摘要IN_PROMPT
2_floating_promptAuthor’s Note浮動提示IN_CHAT(depth=4)
3_vectorsVectors向量記憶搜尋結果IN_PROMPT
4_vectors_data_bankData Bank向量資料庫搜尋結果IN_PROMPT
chromadbChromaDB智慧上下文IN_PROMPT
PERSONA_DESCRIPTION人設系統使用者角色描述IN_PROMPT
QUIET_PROMPT系統內部靜默提示(不顯示於 UI)末尾
DEPTH_PROMPT角色卡角色的深度提示IN_CHAT

★ 設計重點:把「誰要注入」和「注入到哪」解耦。摘要、向量記憶、人設、AN 各自只管產生文字與宣告位置,組裝器統一處理。要新增一種記憶來源,不必改組裝流程。

IN_CHAT 深度注入的演算法(doChatInject)

  1. 把聊天歷史反轉(最新在前),此時陣列索引剛好等於 depth;
  2. 從 depth=0 跑到 maxDepth,每一層收集所有 depth=i 的注入;
  3. 同一深度有多筆時,依角色優先序 SYSTEM → USER → ASSISTANT 排列,插到位置 i;
  4. 再把聊天歷史反轉回來。

反轉的好處:depth 是「從底部數」的概念,反轉後直接用索引插入,不用每次拿長度去換算。

固定位置 vs 深度注入:怎麼選

考量固定位置(IN_PROMPT)深度注入(IN_CHAT)
模型注意力離生成點遠,較低可貼近生成點,較高
穩定性永遠在同一位置位置隨聊天長度浮動
適合角色定義、世界觀情境提示、行為指引
被裁切風險低(固定內容先放入預算)有(聊天歷史太長時)

經驗法則:「是什麼」放固定位置,「現在要怎樣」放深度注入。

⚠️ 注意 / 什麼時候不適用

  • depth 太淺會壓過對話本身:depth=0 的強指令可能讓每則回覆都在呼應它,失去自然感;先從 depth 3–5 試(經驗推論,原文預設 depth=4)。
  • role 選 user/assistant 可能有副作用(經驗推論,非原文件結論):模型可能把它當成真實對話的一部分而回應或模仿;中性的指令用 system 較安全(但部分 API 對聊天中段的 system 訊息支援度不同,需實測)。
  • 深度注入跟著聊天被裁切(推論):Token 預算不足時聊天從舊的砍起,注入點附近的訊息若被砍,位置會移動;極端情況下整段聊天放不下時注入也沒地方放。
  • 多個擴展同時 IN_CHAT 注入同一深度會擠在一起,順序只依角色優先序決定,彼此的前後關係不一定是你要的。
  • 原文件中 AN 的 position=2 描述為「場景前」,而 Extension Prompts 的值 2(BEFORE_PROMPT)描述為「整個 prompt 之前」,兩處說法不一致,實作前以程式碼為準。

🧪 我實際套用的紀錄

  • (尚無)

🔗 相關