Electron LanguageModelUtility 完全解析:在 Utility 进程中构建本地 AI 语言模型能力 Electron LanguageModelUtility 完全解析在 Utility 进程中构建本地 AI 语言模型能力【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electronElectron 通过实验性的 Prompt API 让渲染进程可以调用本地大语言模型LLM而LanguageModelUtility是这条链路上运行在 Utility 进程中的核心类。本文基于当前仓库中 docs/api/language-model-utility.md 的完整 API 定义展开逐一讲清构造器、静态方法、实例属性与实例方法的语义结合 结构类型文档 与 lib/utility/api/language-model-utility.ts 的实现源码说明它如何与 localAIHandler 协作帮助你在 Electron 应用中落地本地 AI 推理能力。一、类定位Utility 进程中的本地 AI 语言模型实现LanguageModelUtility的官方定位是 “Implement local AI language models”实现本地 AI 语言模型其所属进程为Utility 进程见 glossary 中对 Utility 进程的定义。这个设计符合 Electron 的多进程模型重计算、可能崩溃的模型推理被隔离在主进程与渲染进程之外的独立 Utility 进程中运行主进程通过session注册本地 AI 处理器渲染进程通过 Prompt API 发起请求三者通过 IPC/Mojo 边界解耦。从源码结构看该类的 JavaScript 侧实现由以下文件组织lib/utility/api/language-model-utility.tsLanguageModelUtility类的 TS 实现lib/utility/api/module-list.ts将LanguageModelUtility与localAIHandler两个模块注册进 Utility 进程的模块清单lib/utility/api/local-ai-handler.tslocalAIHandler模块直接包装 C 侧绑定electron_utility_local_ai_handler并挂上EventEmitter原型lib/utility/init.tsUtility 进程初始化时通过v8Util.setHiddenValue注册isLanguageModel/isLanguageModelClass判断函数供框架识别传递到各进程中的LanguageModelUtility实例。二、构造器new LanguageModelUtility(initialState)构造器接收一个initialState对象包含两个数字字段字段类型说明contextUsagenumber当前上下文窗口中已占用的 token 数contextWindownumber上下文窗口总容量token 数对应源码language-model-utility.ts#L10-L13中构造器只是把这两个值直接赋给实例属性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; } // ... }文档中有一条明确的注意事项NOTE不要在类之外直接调用该构造器因为这样创建的实例不会与localAIHandler正确建立连接。创建实例的正确方式是下一节的静态方法LanguageModelUtility.create()。三、静态方法3.1LanguageModelUtility.create(options)实验性optionsLanguageModelCreateOptions返回值PromiseLanguageModelUtility使用提供的options创建一个新的LanguageModelUtility实例。LanguageModelCreateOptions结构继承自LanguageModelCreateCoreOptions完整字段如下结合 language-model-create-options.md 与 language-model-create-core-options.md字段类型是否可选说明signalAbortSignal否取消信号用于中止创建过程initialPromptsLanguageModelMessage[]是创建时注入的初始提示消息列表expectedInputsLanguageModelExpected[]是声明模型预期接收的输入模态expectedOutputsLanguageModelExpected[]是声明模型预期产生的输出模态其中LanguageModelExpected的字段为typestringtext/image/audio三者之一languagesstring[]可选语言列表。从当前仓库的 JS 侧实现看create()目前是一个占位实现返回contextUsage: 0, contextWindow: 0的空上下文实例language-model-utility.ts#L15-L20static async create(): PromiseLanguageModelUtility { return new LanguageModelUtility({ contextUsage: 0, contextWindow: 0 }); }这说明 JS 层只是整个调用链的端点之一真正的模型装载发生在 C 侧的 Prompt API 基础设施中JavaScript 实现负责承载上下文状态并暴露 API 形状。3.2LanguageModelUtility.availability([options])实验性options可选LanguageModelCreateCoreOptions返回值Promisestring探测语言模型的可用性返回以下四个字符串之一返回值含义available模型已就绪可立即使用downloadable模型尚未下载可以下载downloading模型正在下载中unavailable当前环境下模型不可用该状态机对应用端做 UI 引导非常关键在展示“开始对话”之前先调用availability()判断是否需要先触发模型下载流程。当前 JS 侧实现同样为占位逻辑固定返回availablelanguage-model-utility.ts#L22-L24真实判定逻辑在底层实现中完成。四、实例属性languageModelUtility.contextUsage实验性number表示当前上下文窗口中已使用的 token 数量。languageModelUtility.contextWindow实验性number表示上下文窗口总大小token 数。这两个属性与构造器参数一一对应是衡量“还能再塞多少上下文”的直接依据可用余量约为contextWindow - contextUsage。五、实例方法5.1languageModelUtility.prompt(input, options)实验性inputLanguageModelMessage[]optionsLanguageModelPromptOptions返回值Promisestring | Promiseimport(stream/web).ReadableStreamstring向模型发起提示并获取响应。返回值是Promisestring或PromiseReadableStreamstring的联合类型即调用方既可以拿到完整的字符串响应也可以消费一个文本流适合逐字渲染的对话界面。LanguageModelPromptOptions的字段见 language-model-prompt-options.md字段类型是否可选说明responseConstraintObject | RegExp是JSON Schema 对象或正则表达式用于约束响应必须匹配指定结构结构化输出signalAbortSignal否取消信号LanguageModelMessage的结构见 language-model-message.md字段类型是否可选说明rolestring否取值system/user/assistantcontentLanguageModelMessageContent[]否消息内容数组prefixboolean是标记是否为前缀消息LanguageModelMessageContent则支持多模态见 language-model-message-content.md字段类型说明typestring取值text/image/audiovalueArrayBuffer | string文本内容用 string二进制内容用 ArrayBuffer一个符合上述结构的调用示例参数形状以文档为准const response await lm.prompt( [ { role: system, content: [{ type: text, value: You are a helpful assistant. }] }, { role: user, content: [{ type: text, value: 总结这段话的核心观点。 }] } ], { signal: new AbortController().signal, responseConstraint: { type: object, properties: { summary: { type: string } } } } );5.2languageModelUtility.append(input, options)实验性inputLanguageModelMessage[]optionsLanguageModelAppendOptions仅含必选字段signal: AbortSignal返回值Promiseundefined向模型追加消息但不触发响应生成用于多轮对话中维护上下文例如把上一轮的 assistant 回复回填进会话历史。对应 JS 实现为空的 async 方法language-model-utility.ts#L30。5.3languageModelUtility.measureContextUsage(input, options)实验性inputLanguageModelMessage[]optionsLanguageModelPromptOptions返回值Promisenumber测量给定输入会占用多少 token但不实际发起推理。这是实现“输入框剩余 token 提示”“上下文超限预警”的配套 API先measureContextUsage再决定是否prompt。JS 侧占位实现返回0language-model-utility.ts#L32-L34。5.4languageModelUtility.clone(options)实验性optionsLanguageModelCloneOptions仅含必选字段signal: AbortSignal返回值PromiseLanguageModelUtility克隆一个LanguageModelUtility克隆出的实例保留原有的上下文与初始提示。从源码实现看克隆即把当前的contextUsage与contextWindow复制到新实例language-model-utility.ts#L36-L41async clone() { return new LanguageModelUtility({ contextUsage: this.contextUsage, contextWindow: this.contextWindow }); }典型场景是从一个已预热上下文的会话派生出独立分支如并行探索多个问题分支之间互不污染。5.5languageModelUtility.destroy()实验性销毁模型同时中止所有正在进行中的执行。JS 侧实现为空操作language-model-utility.ts#L43资源释放由底层完成。调用方应在会话结束、窗口关闭时显式调用避免遗留模型状态占用 Utility 进程资源。六、与 localAIHandler 的协作关系LanguageModelUtility不是孤立使用的。文档对构造器的 NOTE 提示它必须与localAIHandler正确连接而 docs/api/local-ai-handler.md 说明了这条链路的另一半主进程侧通过ses.registerLocalAIHandler(handler)把一个脚本注册到指定 session该脚本即运行在 Utility 进程中Utility 进程侧脚本调用localAIHandler.setPromptAPIHandler(promptAPIHandler)注册 Prompt API 绑定处理器处理器签名为Functiontypeof LanguageModelUtility | null接收details对象包含webContentsId发起 Prompt API 调用的 WebContents 唯一 idsecurityOrigin调用页面的 originframeToken发起调用 frame 的 frame tokenrenderProcessId承载该 frame 的渲染进程 id。请求路由每对webContentsId与securityOrigin触发一次绑定请求。处理器返回null即拒绝该渲染进程创建新的 Prompt API 会话若要使既有 Prompt API 会话失效则用ses.registerLocalAIHandler(null)清除 handler。排队语义若渲染进程在setPromptAPIHandler()调用之前就调用了 Prompt API请求会被排队handler 设置后统一冲刷排队过多时会丢弃最旧的待处理请求并拒绝渲染进程中的 pending promise。文档因此建议尽早调用setPromptAPIHandler()。从源码结构看Utility 进程中的localAIHandler模块直接是 C 绑定electron_utility_local_ai_handler的 JS 包装lib/utility/api/local-ai-handler.ts而 lib/utility/init.ts 中注册的isLanguageModel/isLanguageModelClass隐藏值则是框架在跨进程传递LanguageModelUtility实例时进行类型识别的机制。仓库中的功能测试 spec/api-local-ai-handler-spec.ts 也表明localAIHandler模块的行为受 Prompt API 特性开关控制features.isPromptAPIEnabled()为真时才执行。七、API 使用小结将文档定义的 API 汇总为速查表成员签名返回值用途new LanguageModelUtility(initialState)initialState: { contextUsage, contextWindow }实例仅限框架内部使用勿直接构造LanguageModelUtility.create(options)options: LanguageModelCreateOptionsPromiseLanguageModelUtility创建实例推荐入口LanguageModelUtility.availability([options])options?: LanguageModelCreateCoreOptionsPromisestring返回available/downloadable/downloading/unavailableinstance.contextUsage—number当前已用 token 数instance.contextWindow—number上下文窗口容量tokeninstance.prompt(input, options)消息数组 Prompt 选项Promisestring \| PromiseReadableStreamstring发起推理支持结构化响应约束instance.append(input, options)消息数组 signalPromiseundefined仅追加上下文不触发响应instance.measureContextUsage(input, options)消息数组 Prompt 选项Promisenumber预估算力/上下文占用instance.clone(options)LanguageModelCloneOptionsPromiseLanguageModelUtility保留上下文与初始提示地克隆instance.destroy()—无销毁模型并中止进行中的执行需要说明的是该 API 族整体标注为Experimental当前仓库的 JavaScript 实现lib/utility/api/language-model-utility.ts对create、availability、prompt、measureContextUsage等均为形状正确的占位实现真实的模型装载与推理由 C 侧 Prompt API 基础设施承担且相关功能受 Prompt API 特性开关控制。在应用层使用这些 API 时应以availability()的结果驱动 UI 流程用contextUsage/contextWindow监控上下文水位并在会话结束时调用destroy()释放资源。【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

最新新闻

Homebrew版本信息转JSON:环境盘点与自动化实践

Homebrew版本信息转JSON:环境盘点与自动化实践

Mac 上写代码的人,十个有九个绕不开 Homebrew。装软件一个brew install,查依赖一个brew info,升级一条brew upgrade,看似简单,但真要让你把"这台机器上到底装了哪些包、各自是什么版本、哪些是你主动装的、哪些只…

2026/9/7 19:03:59
VSCode调试C语言scanf输入无效与跳过的解决方案

VSCode调试C语言scanf输入无效与跳过的解决方案

如果你是个刚接触C语言的新手,折腾了大半天把VSCode的C/C环境配好,开开心心按下F5准备调试人生中第一个带scanf()的程序,结果却对着屏幕发呆:程序运行到scanf()那行就不动了,“调试控制台”里光标一闪一闪,…

2026/9/7 19:03:59
C++内存泄漏检测全攻略:从ASan到Valgrind的工具与实践

C++内存泄漏检测全攻略:从ASan到Valgrind的工具与实践

1. 为什么每个 C 开发者都需要一套内存泄漏检测方案内存泄漏大概是 C 项目里最让人头疼的问题之一。不像数组越界会立刻崩溃,泄漏是慢性的——程序跑着跑着内存占用越来越高,最后在客户现场或者线上环境突然挂掉,而你本地怎么复现都复现不出来…

2026/9/7 19:03:59
Material UI 新手 FAQ 实战解析:模态滚动锁与 .mui-fixed、全局禁用 Ripple 与过渡、SSR 排错指南

Material UI 新手 FAQ 实战解析:模态滚动锁与 .mui-fixed、全局禁用 Ripple 与过渡、SSR 排错指南

Material UI 新手 FAQ 实战解析:模态滚动锁与 .mui-fixed、全局禁用 Ripple 与过渡、SSR 排错指南 【免费下载链接】material-ui Material UI: Comprehensive React component library that implements Googles Material Design. Free forever. 项目地址: https:/…

2026/9/7 19:03:59
中小企业零门槛数字化招聘:用多维表格3天搭起全流程

中小企业零门槛数字化招聘:用多维表格3天搭起全流程

先交代背景:我最近帮几家中小企业搭过招聘流程的数字化方案,都是没有IT团队、预算有限、连专职HR都只有一两个人的那种。前后不折腾什么高端系统,就把招聘这件事从“微信聊着聊着就乱了”变成了“点开表格就知道候选人到哪一步了”。这篇文章…

2026/9/7 19:03:59
C语言手写链表与哈希表:哨兵节点、哈希冲突与工程实践

C语言手写链表与哈希表:哨兵节点、哈希冲突与工程实践

1. 造轮子之前:为什么还要自己写链表与哈希表如果你去面试一个C语言岗位,面试官让你白板写一个单链表反转,你大概率觉得这题"太基础了"。但真的动手时,很多人写着写着就卡住了——头节点为空怎么办、只有一个节点怎么办…

2026/9/7 18:58:59