Skip to content

預設與提示詞

預設管理 API,以及把訊息組裝成帶角色卡和世界書的提示詞的相關 API。

預設 API

context.presets 提供了統一的預設管理介面,替代直接匯入 PresetManager 內部模組。

presets.list

ts
presets.list(collection?: string): Array<PresetRef>

列出指定集合的所有已儲存預設。collection 為預設集合名(如 'openai')。

presets.getSelected

ts
presets.getSelected(collection?: string): PresetRef | null

取得當前選中的預設參照。如果當前選中的是角色卡綁定的執行時預設,回傳 null

presets.getLive

ts
presets.getLive(collection?: string): PresetBody | null

取得當前 UI 中正在編輯的預設內容(包括未儲存的修改)。適合需要讀取當前實際生效設定的場景。

presets.getStored

ts
presets.getStored(ref: { collection: string, name: string }): PresetBody | null

取得指定預設的已儲存內容。適合跨預設比較或複製內容。

presets.save

ts
presets.save(
  ref: { collection: string, name: string },
  body: PresetBody
): Promise<void>

儲存預設內容。

presets.resolve

ts
presets.resolve(
  target?: PresetRef | string,
  options?: { collection?: string, defaultCollection?: string, allowMissingName?: boolean }
): { collection: string, name: string } | null

把一個預設引用規範化成 { collection, name }。這是純粹的名稱解析輔助函式,不會回傳連線資訊。可傳入 PresetRef、表示集合名稱的字串(解析成該集合當前選中的預設)、或 null(依 options.collection 解析當前選中的預設)。無法確定 collection 或 name 時回傳 null

想找連線設定解析?

這個函式不會回傳 API 端點、模型或金鑰資訊。要把 connection manager 的 profile 解析成 sendOpenAIRequest 能吃的連線設定,請用 context.connectionProfiles.resolve

presets.state

ts
presets.state.update(
  namespace: string,
  updater: (current: any) => any,
  options?: { target: PresetRef }
): Promise<void>

管理綁定到預設的外掛執行時/會話資料。這些資料不會隨預設匯出,僅用於外掛的執行時狀態。

使用規則

  • list()getSelected() 只回傳已儲存的預設
  • 編輯中的預設用 getLive()
  • 角色卡綁定的執行時預設不算「已儲存」,getSelected() 回傳 null,但 getLive() 仍可讀取
  • 不要將外掛執行時資料塞進預設 body,使用 presets.state.*

提示詞與世界書組裝

buildPresetAwarePromptMessages

ts
buildPresetAwarePromptMessages(options: {
  messages: Array<{ role: string, content: string }>,
  envelopeOptions?: {
    includeCharacterCard?: boolean,
    api?: string,
    promptPresetName?: string,
  },
  promptPresetName?: string,
  runtimeWorldInfo?: object,
}): PromptMessage[]

基於當前預設設定,將外掛的訊息按照 prompt 預設的排列順序組裝為可發送給 API 的提示詞訊息列表。這是一個可選的組裝工具——簡單的 LLM 呼叫不需要它,只有當你需要複用角色卡、世界書或 prompt 範本時才需要使用。

參數說明:

參數說明
messages要發送的訊息陣列,每條訊息包含 role'system'/'user'/'assistant')和 content
envelopeOptions.includeCharacterCard是否在提示詞中包含當前角色卡的設定(預設 true
envelopeOptions.api指定使用的 API 類型(如 'openai'),不指定則使用當前連線
envelopeOptions.promptPresetName指定使用的預設名稱,不指定則使用當前預設
promptPresetNameenvelopeOptions.promptPresetName 相同,頂層快捷方式
runtimeWorldInfo預先解析好的世界書啟動結果(透過 resolveWorldInfoForMessages 取得)

關鍵行為:

  • 保留活躍預設中聊天歷史以外的內容(系統提示、角色描述等)
  • 僅替換聊天歷史部分為你提供的 messages
  • 如果提供了 runtimeWorldInfo,世界書條目會被注入到對應位置
  • 如果指定了 promptPresetName,會使用該預設的提示詞範本而非當前預設

實際使用範例(參考記憶圖外掛的召回流程):

js
// 1. 先解析世界書啟動結果
const runtimeWorldInfo = await context.resolveWorldInfoForMessages(
  resolverMessages,
  {
    type: 'quiet',
    fallbackToCurrentChat: false,
    postActivationHook: rewriteDepthWorldInfoToAfter, // 重寫指令:將 depth 類型的世界書條目移到 after 位置
  }
);

// 2. 組裝提示詞
const promptMessages = context.buildPresetAwarePromptMessages({
  messages: [
    { role: 'system', content: '你是一個記憶分析助手...' },
    { role: 'user', content: '請分析以下對話中的關鍵資訊...' },
  ],
  envelopeOptions: {
    includeCharacterCard: true,
    api: envelopeApi,
    promptPresetName: selectedPromptPresetName,
  },
  promptPresetName: selectedPromptPresetName,
  runtimeWorldInfo: runtimeWorldInfo,
});

// 3. 發送給 LLM
import { sendOpenAIRequest } from '../../../openai.js';
const response = await sendOpenAIRequest('quiet', promptMessages, signal, {
 requestScope: 'extension_internal',
});

關於後處理鉤子(postActivationHook)

resolveWorldInfoForMessagespostActivationHook 參數允許你在世界書啟動後、注入前對條目進行任意修改——包括修改內容、調整注入位置和深度、甚至增刪條目。hook 接收歸一化後的完整世界書 payload 並回傳修改後的版本。例如記憶圖外掛利用此鉤子將 depth 類型的世界書條目重寫到 after 位置,避免插入到聊天深度中干擾外掛自己的指令。

resolveWorldInfoForMessages

ts
resolveWorldInfoForMessages(
  messages: Array<{ role: string, content: string }>,
  options?: {
    type?: string,
    fallbackToCurrentChat?: boolean,
    postActivationHook?: (entries: object) => object,
  }
): Promise<object>

對指定訊息執行世界書啟動掃描,回傳啟動結果。這相當於對自訂訊息進行一次世界書「重掃」。

參數說明:

參數說明
messages用於觸發世界書關鍵詞匹配的訊息列表
options.type啟動類型(如 'quiet' 表示靜默掃描,不影響主對話)
options.fallbackToCurrentChat如果 messages 為空,是否回退到當前聊天訊息
options.postActivationHook啟動後的鉤子函數,接收完整的世界書 payload,可以修改條目的內容、位置、深度,或增刪條目

回傳的物件包含 worldInfoBeforeEntriesworldInfoAfterEntriesworldInfoDepth 等欄位,可以直接傳給 buildPresetAwarePromptMessagesruntimeWorldInfo 參數。

世界書重掃

resolveWorldInfoForMessages 本質上就是對自訂訊息進行世界書重掃。外掛可以用它來:

  • 為獨立的 LLM 呼叫取得相關的世界書條目
  • 測試特定訊息會觸發哪些世界書條目
  • 在不影響主對話的情況下進行世界書啟動模擬

推薦的獨立 LLM 呼叫模式

當外掛需要進行獨立的 LLM 呼叫(如彈窗中的 AI 輔助功能)時,推薦以下模式:

js
import { sendOpenAIRequest } from '../../../openai.js';
const context = Luker.getContext();

// 1. 解析世界書啟動結果
const wi = await context.resolveWorldInfoForMessages(myCustomMessages, {
 type: 'quiet',
 fallbackToCurrentChat: false,
});

// 2. 組裝提示詞(注入角色卡、世界書、按 prompt_order 排列)
const requestMessages = context.buildPresetAwarePromptMessages({
 messages: myCustomMessages,
 runtimeWorldInfo: wi,
});

// 3. 發送請求
const result = await sendOpenAIRequest('quiet', requestMessages, signal, {
 requestScope: 'extension_internal',
});

如果不需要角色卡和世界書,可以跳過步驟 1-2,直接傳 messages 給 sendOpenAIRequestsendOpenAIRequest 詳見 生成請求

提示詞信封檢視

對於診斷型 UI 和「預覽即將發送內容」工具,外掛可以讀取已組裝的 prompt 信封與排版,而不發起請求。

getActivePromptPresetEnvelope

ts
getActivePromptPresetEnvelope(options?: {
    includeCharacterCard?: boolean,
    api?: string,
    promptPresetName?: string,
    completionPresetName?: string,
    contextPresetName?: string,
    instructPresetName?: string,
    syspromptPresetName?: string,
    reasoningPresetName?: string,
}): PromptPresetEnvelope

回傳已解析 prompt 設定的快照,包含:

  • mainApi / completionApi —— 活躍的 API 識別碼
  • presetRefs —— 已解析的 completion / context / instruct / sysprompt / reasoning 預設名稱
  • promptCore —— 每個預設中提取出的 prompt 相關欄位
  • promptLayout —— 合併後的 Luker 排版(來自 extensions.luker.prompt_layout
  • promptCatalog —— prompt.identifier{ name, role, content, marker, systemPrompt } 的映射
  • characterCard —— 當前角色欄位(當 includeCharacterCard !== false 時)

這就是 buildPresetAwarePromptMessages 內部使用的同一份資料。在發送前向使用者展示「外掛的請求會長什麼樣」時很有用。

getActivePromptLayout

ts
getActivePromptLayout(options?: object): PromptLayoutEntry[]

便利存取器,僅回傳合併後的 prompt 排版。每個條目包含 idenabledorderrolephasesourcecontentpathpromptIdentifiertags

formatPromptPresetEnvelope

ts
formatPromptPresetEnvelope(envelope?: object, options?: { label?: string }): string

把信封格式化成 [[LABEL]]\n<json> 形式以嵌入到另一個 prompt 中(例如委派給需要對使用者 prompt 設定進行推理的 meta-LLM)。未提供時預設取當前信封。

js
const ctx = Luker.getContext();
const envelope = ctx.getActivePromptPresetEnvelope({ includeCharacterCard: true });
const serialized = ctx.formatPromptPresetEnvelope(envelope);
console.log(serialized);

推理

推理輔助函式用於解析和渲染推理模型(Claude reasoning、DeepSeek-R1、o1 等)發出的 <thinking>...</thinking> 風格區塊。

parseReasoningFromString

ts
parseReasoningFromString(
    text: string,
    options?: { strict?: boolean },
    template?: ReasoningTemplate | null,
): { reasoning: string, content: string } | null

依照推理範本(或當前活躍的 power_user.reasoning 範本)的 prefixsuffix,把模型輸出字串切成 reasoningcontent。範本缺 prefix / suffix 或解析失敗時回傳 null

選項說明
stricttrue(預設)時,prefix 必須出現在開頭(在空白之後)。為 false 時,會在任何位置查找

getReasoningTemplateByName

ts
getReasoningTemplateByName(name: string): ReasoningTemplate

按名稱查找推理範本。找不到時擲出 Error('Unknown reasoning template name: "<name>"')。回傳的範本應視為唯讀。

updateReasoningUI

ts
updateReasoningUI(
    messageIdOrElement: number | HTMLElement | JQuery,
    options?: { reset?: boolean },
): void

觸發某條訊息推理區塊的 UI 重新整理。可傳聊天索引、原始 DOM 元素或 JQuery 包裝物件。reset: true 會跳過讀取訊息當前的推理狀態——在 swipe 期間新推理還沒寫入時用得到。

js
const ctx = Luker.getContext();
const parsed = ctx.parseReasoningFromString(modelOutput);
if (parsed) {
    console.log('Reasoning:', parsed.reasoning);
    console.log('Final answer:', parsed.content);
}

設定視圖(唯讀)

下面這些屬性暴露實時設定物件。它們是可變的參照——只能透過正規 API(presets.savesaveSettingsDebounced 等)寫入。直接突變可能無法正確持久化。

chatCompletionSettings

ts
context.chatCompletionSettings: object

oai_settings 的參照。唯讀視圖,用於檢視當前活躍的 chat completion source、模型與參數。

textCompletionSettings

ts
context.textCompletionSettings: object

textgenerationwebui_settings 的參照。當前 text completion 後端的唯讀視圖。

powerUserSettings

ts
context.powerUserSettings: object

power_user 的參照。持有 tokenizer 選擇、推理範本選擇、訊息顯示偏好和其他使用者級設定。

透過 API 寫入而非直接突變

這些視圖僅為檢視而暴露。直接寫入它們可能繞過防抖儲存邏輯。要更改連線或模型,請使用面向使用者的 UI 或 presets.save。要更改生成參數,請使用 chat completion 預設。

基於 SillyTavern 建構