程中構(gòu)建本地 AI 語(yǔ)言模型能力)
Electron LanguageModelUtility 完全解析在 Utility 進(jìn)程中構(gòu)建本地 AI 語(yǔ)言模型能力【免費(fèi)下載鏈接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS項(xiàng)目地址: https://gitcode.com/GitHub_Trending/el/electronElectron 通過實(shí)驗(yàn)性的 Prompt API 讓渲染進(jìn)程可以調(diào)用本地大語(yǔ)言模型LLM而LanguageModelUtility是這條鏈路上運(yùn)行在 Utility 進(jìn)程中的核心類。本文基于當(dāng)前倉(cāng)庫(kù)中 docs/api/language-model-utility.md 的完整 API 定義展開逐一講清構(gòu)造器、靜態(tài)方法、實(shí)例屬性與實(shí)例方法的語(yǔ)義結(jié)合 結(jié)構(gòu)類型文檔 與 lib/utility/api/language-model-utility.ts 的實(shí)現(xiàn)源碼說(shuō)明它如何與 localAIHandler 協(xié)作幫助你在 Electron 應(yīng)用中落地本地 AI 推理能力。一、類定位Utility 進(jìn)程中的本地 AI 語(yǔ)言模型實(shí)現(xiàn)LanguageModelUtility的官方定位是 “Implement local AI language models”實(shí)現(xiàn)本地 AI 語(yǔ)言模型其所屬進(jìn)程為Utility 進(jìn)程見 glossary 中對(duì) Utility 進(jìn)程的定義。這個(gè)設(shè)計(jì)符合 Electron 的多進(jìn)程模型重計(jì)算、可能崩潰的模型推理被隔離在主進(jìn)程與渲染進(jìn)程之外的獨(dú)立 Utility 進(jìn)程中運(yùn)行主進(jìn)程通過session注冊(cè)本地 AI 處理器渲染進(jìn)程通過 Prompt API 發(fā)起請(qǐng)求三者通過 IPC/Mojo 邊界解耦。從源碼結(jié)構(gòu)看該類的 JavaScript 側(cè)實(shí)現(xiàn)由以下文件組織lib/utility/api/language-model-utility.tsLanguageModelUtility類的 TS 實(shí)現(xiàn)lib/utility/api/module-list.ts將LanguageModelUtility與localAIHandler兩個(gè)模塊注冊(cè)進(jìn) Utility 進(jìn)程的模塊清單lib/utility/api/local-ai-handler.tslocalAIHandler模塊直接包裝 C 側(cè)綁定electron_utility_local_ai_handler并掛上EventEmitter原型lib/utility/init.tsUtility 進(jìn)程初始化時(shí)通過v8Util.setHiddenValue注冊(cè)isLanguageModel/isLanguageModelClass判斷函數(shù)供框架識(shí)別傳遞到各進(jìn)程中的LanguageModelUtility實(shí)例。二、構(gòu)造器new LanguageModelUtility(initialState)構(gòu)造器接收一個(gè)initialState對(duì)象包含兩個(gè)數(shù)字字段字段類型說(shuō)明contextUsagenumber當(dāng)前上下文窗口中已占用的 token 數(shù)contextWindownumber上下文窗口總?cè)萘縯oken 數(shù)對(duì)應(yīng)源碼language-model-utility.ts#L10-L13中構(gòu)造器只是把這兩個(gè)值直接賦給實(shí)例屬性interface LanguageModelConstructorValues { contextUsage: number; contextWindow: number; } export default class LanguageModelUtility implements Electron.LanguageModelUtility { contextUsage: number; contextWindow: number; constructor(values: LanguageModelConstructorValues) { this.contextUsage values.contextUsage; this.contextWindow values.contextWindow; } // ... }文檔中有一條明確的注意事項(xiàng)NOTE不要在類之外直接調(diào)用該構(gòu)造器因?yàn)檫@樣創(chuàng)建的實(shí)例不會(huì)與localAIHandler正確建立連接。創(chuàng)建實(shí)例的正確方式是下一節(jié)的靜態(tài)方法LanguageModelUtility.create()。三、靜態(tài)方法3.1LanguageModelUtility.create(options)實(shí)驗(yàn)性optionsLanguageModelCreateOptions返回值PromiseLanguageModelUtility使用提供的options創(chuàng)建一個(gè)新的LanguageModelUtility實(shí)例。LanguageModelCreateOptions結(jié)構(gòu)繼承自LanguageModelCreateCoreOptions完整字段如下結(jié)合 language-model-create-options.md 與 language-model-create-core-options.md字段類型是否可選說(shuō)明signalAbortSignal否取消信號(hào)用于中止創(chuàng)建過程initialPromptsLanguageModelMessage[]是創(chuàng)建時(shí)注入的初始提示消息列表expectedInputsLanguageModelExpected[]是聲明模型預(yù)期接收的輸入模態(tài)expectedOutputsLanguageModelExpected[]是聲明模型預(yù)期產(chǎn)生的輸出模態(tài)其中LanguageModelExpected的字段為typestringtext/image/audio三者之一languagesstring[]可選語(yǔ)言列表。從當(dāng)前倉(cāng)庫(kù)的 JS 側(cè)實(shí)現(xiàn)看create()目前是一個(gè)占位實(shí)現(xiàn)返回contextUsage: 0, contextWindow: 0的空上下文實(shí)例language-model-utility.ts#L15-L20static async create(): PromiseLanguageModelUtility { return new LanguageModelUtility({ contextUsage: 0, contextWindow: 0 }); }這說(shuō)明 JS 層只是整個(gè)調(diào)用鏈的端點(diǎn)之一真正的模型裝載發(fā)生在 C 側(cè)的 Prompt API 基礎(chǔ)設(shè)施中JavaScript 實(shí)現(xiàn)負(fù)責(zé)承載上下文狀態(tài)并暴露 API 形狀。3.2LanguageModelUtility.availability([options])實(shí)驗(yàn)性options可選LanguageModelCreateCoreOptions返回值Promisestring探測(cè)語(yǔ)言模型的可用性返回以下四個(gè)字符串之一返回值含義available模型已就緒可立即使用downloadable模型尚未下載可以下載downloading模型正在下載中unavailable當(dāng)前環(huán)境下模型不可用該狀態(tài)機(jī)對(duì)應(yīng)用端做 UI 引導(dǎo)非常關(guān)鍵在展示“開始對(duì)話”之前先調(diào)用availability()判斷是否需要先觸發(fā)模型下載流程。當(dāng)前 JS 側(cè)實(shí)現(xiàn)同樣為占位邏輯固定返回availablelanguage-model-utility.ts#L22-L24真實(shí)判定邏輯在底層實(shí)現(xiàn)中完成。四、實(shí)例屬性languageModelUtility.contextUsage實(shí)驗(yàn)性number表示當(dāng)前上下文窗口中已使用的 token 數(shù)量。languageModelUtility.contextWindow實(shí)驗(yàn)性number表示上下文窗口總大小token 數(shù)。這兩個(gè)屬性與構(gòu)造器參數(shù)一一對(duì)應(yīng)是衡量“還能再塞多少上下文”的直接依據(jù)可用余量約為contextWindow - contextUsage。五、實(shí)例方法5.1languageModelUtility.prompt(input, options)實(shí)驗(yàn)性inputLanguageModelMessage[]optionsLanguageModelPromptOptions返回值Promisestring | Promiseimport(stream/web).ReadableStreamstring向模型發(fā)起提示并獲取響應(yīng)。返回值是Promisestring或PromiseReadableStreamstring的聯(lián)合類型即調(diào)用方既可以拿到完整的字符串響應(yīng)也可以消費(fèi)一個(gè)文本流適合逐字渲染的對(duì)話界面。LanguageModelPromptOptions的字段見 language-model-prompt-options.md字段類型是否可選說(shuō)明responseConstraintObject | RegExp是JSON Schema 對(duì)象或正則表達(dá)式用于約束響應(yīng)必須匹配指定結(jié)構(gòu)結(jié)構(gòu)化輸出signalAbortSignal否取消信號(hào)LanguageModelMessage的結(jié)構(gòu)見 language-model-message.md字段類型是否可選說(shuō)明rolestring否取值system/user/assistantcontentLanguageModelMessageContent[]否消息內(nèi)容數(shù)組prefixboolean是標(biāo)記是否為前綴消息LanguageModelMessageContent則支持多模態(tài)見 language-model-message-content.md字段類型說(shuō)明typestring取值text/image/audiovalueArrayBuffer | string文本內(nèi)容用 string二進(jìn)制內(nèi)容用 ArrayBuffer一個(gè)符合上述結(jié)構(gòu)的調(diào)用示例參數(shù)形狀以文檔為準(zhǔn)const response await lm.prompt( [ { role: system, content: [{ type: text, value: You are a helpful assistant. }] }, { role: user, content: [{ type: text, value: 總結(jié)這段話的核心觀點(diǎn)。 }] } ], { signal: new AbortController().signal, responseConstraint: { type: object, properties: { summary: { type: string } } } } );5.2languageModelUtility.append(input, options)實(shí)驗(yàn)性inputLanguageModelMessage[]optionsLanguageModelAppendOptions僅含必選字段signal: AbortSignal返回值Promiseundefined向模型追加消息但不觸發(fā)響應(yīng)生成用于多輪對(duì)話中維護(hù)上下文例如把上一輪的 assistant 回復(fù)回填進(jìn)會(huì)話歷史。對(duì)應(yīng) JS 實(shí)現(xiàn)為空的 async 方法language-model-utility.ts#L30。5.3languageModelUtility.measureContextUsage(input, options)實(shí)驗(yàn)性inputLanguageModelMessage[]optionsLanguageModelPromptOptions返回值Promisenumber測(cè)量給定輸入會(huì)占用多少 token但不實(shí)際發(fā)起推理。這是實(shí)現(xiàn)“輸入框剩余 token 提示”“上下文超限預(yù)警”的配套 API先measureContextUsage再?zèng)Q定是否prompt。JS 側(cè)占位實(shí)現(xiàn)返回0language-model-utility.ts#L32-L34。5.4languageModelUtility.clone(options)實(shí)驗(yàn)性optionsLanguageModelCloneOptions僅含必選字段signal: AbortSignal返回值PromiseLanguageModelUtility克隆一個(gè)LanguageModelUtility克隆出的實(shí)例保留原有的上下文與初始提示。從源碼實(shí)現(xiàn)看克隆即把當(dāng)前的contextUsage與contextWindow復(fù)制到新實(shí)例language-model-utility.ts#L36-L41async clone() { return new LanguageModelUtility({ contextUsage: this.contextUsage, contextWindow: this.contextWindow }); }典型場(chǎng)景是從一個(gè)已預(yù)熱上下文的會(huì)話派生出獨(dú)立分支如并行探索多個(gè)問題分支之間互不污染。5.5languageModelUtility.destroy()實(shí)驗(yàn)性銷毀模型同時(shí)中止所有正在進(jìn)行中的執(zhí)行。JS 側(cè)實(shí)現(xiàn)為空操作language-model-utility.ts#L43資源釋放由底層完成。調(diào)用方應(yīng)在會(huì)話結(jié)束、窗口關(guān)閉時(shí)顯式調(diào)用避免遺留模型狀態(tài)占用 Utility 進(jìn)程資源。六、與 localAIHandler 的協(xié)作關(guān)系LanguageModelUtility不是孤立使用的。文檔對(duì)構(gòu)造器的 NOTE 提示它必須與localAIHandler正確連接而 docs/api/local-ai-handler.md 說(shuō)明了這條鏈路的另一半主進(jìn)程側(cè)通過ses.registerLocalAIHandler(handler)把一個(gè)腳本注冊(cè)到指定 session該腳本即運(yùn)行在 Utility 進(jìn)程中Utility 進(jìn)程側(cè)腳本調(diào)用localAIHandler.setPromptAPIHandler(promptAPIHandler)注冊(cè) Prompt API 綁定處理器處理器簽名為Functiontypeof LanguageModelUtility | null接收details對(duì)象包含webContentsId發(fā)起 Prompt API 調(diào)用的 WebContents 唯一 idsecurityOrigin調(diào)用頁(yè)面的 originframeToken發(fā)起調(diào)用 frame 的 frame tokenrenderProcessId承載該 frame 的渲染進(jìn)程 id。請(qǐng)求路由每對(duì)webContentsId與securityOrigin觸發(fā)一次綁定請(qǐng)求。處理器返回null即拒絕該渲染進(jìn)程創(chuàng)建新的 Prompt API 會(huì)話若要使既有 Prompt API 會(huì)話失效則用ses.registerLocalAIHandler(null)清除 handler。排隊(duì)語(yǔ)義若渲染進(jìn)程在setPromptAPIHandler()調(diào)用之前就調(diào)用了 Prompt API請(qǐng)求會(huì)被排隊(duì)handler 設(shè)置后統(tǒng)一沖刷排隊(duì)過多時(shí)會(huì)丟棄最舊的待處理請(qǐng)求并拒絕渲染進(jìn)程中的 pending promise。文檔因此建議盡早調(diào)用setPromptAPIHandler()。從源碼結(jié)構(gòu)看Utility 進(jìn)程中的localAIHandler模塊直接是 C 綁定electron_utility_local_ai_handler的 JS 包裝lib/utility/api/local-ai-handler.ts而 lib/utility/init.ts 中注冊(cè)的isLanguageModel/isLanguageModelClass隱藏值則是框架在跨進(jìn)程傳遞LanguageModelUtility實(shí)例時(shí)進(jìn)行類型識(shí)別的機(jī)制。倉(cāng)庫(kù)中的功能測(cè)試 spec/api-local-ai-handler-spec.ts 也表明localAIHandler模塊的行為受 Prompt API 特性開關(guān)控制features.isPromptAPIEnabled()為真時(shí)才執(zhí)行。七、API 使用小結(jié)將文檔定義的 API 匯總為速查表成員簽名返回值用途new LanguageModelUtility(initialState)initialState: { contextUsage, contextWindow }實(shí)例僅限框架內(nèi)部使用勿直接構(gòu)造LanguageModelUtility.create(options)options: LanguageModelCreateOptionsPromiseLanguageModelUtility創(chuàng)建實(shí)例推薦入口LanguageModelUtility.availability([options])options?: LanguageModelCreateCoreOptionsPromisestring返回available/downloadable/downloading/unavailableinstance.contextUsage—number當(dāng)前已用 token 數(shù)instance.contextWindow—number上下文窗口容量tokeninstance.prompt(input, options)消息數(shù)組 Prompt 選項(xiàng)Promisestring \| PromiseReadableStreamstring發(fā)起推理支持結(jié)構(gòu)化響應(yīng)約束instance.append(input, options)消息數(shù)組 signalPromiseundefined僅追加上下文不觸發(fā)響應(yīng)instance.measureContextUsage(input, options)消息數(shù)組 Prompt 選項(xiàng)Promisenumber預(yù)估算力/上下文占用instance.clone(options)LanguageModelCloneOptionsPromiseLanguageModelUtility保留上下文與初始提示地克隆instance.destroy()—無(wú)銷毀模型并中止進(jìn)行中的執(zhí)行需要說(shuō)明的是該 API 族整體標(biāo)注為Experimental當(dāng)前倉(cāng)庫(kù)的 JavaScript 實(shí)現(xiàn)lib/utility/api/language-model-utility.ts對(duì)create、availability、prompt、measureContextUsage等均為形狀正確的占位實(shí)現(xiàn)真實(shí)的模型裝載與推理由 C 側(cè) Prompt API 基礎(chǔ)設(shè)施承擔(dān)且相關(guān)功能受 Prompt API 特性開關(guān)控制。在應(yīng)用層使用這些 API 時(shí)應(yīng)以availability()的結(jié)果驅(qū)動(dòng) UI 流程用contextUsage/contextWindow監(jiān)控上下文水位并在會(huì)話結(jié)束時(shí)調(diào)用destroy()釋放資源?!久赓M(fèi)下載鏈接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS項(xiàng)目地址: https://gitcode.com/GitHub_Trending/el/electron創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考