@ 学位标志/ 聊天
用于浏览器、工人和节点的插接和播放 AI 聊天:一个模式 内存,任何UI中的无限离线响应. 包裹选择引擎, 管理下载, 匹配快速并重用缓存; wllama CPU 引擎 和一个LiteRT-LM WebGPU引擎在本地运行,每个导出都输入.
演示
打开展示 用于实时聊天演示 浏览 结构 地图演示下载 一次型号,大约1.5GB在CPU引擎上或2.0GB在WebGPU上,然后 在设备上回答.
目录
为什么
- 证明: 多莉丝蒂一个没有签名的PWA,描述
将语音笔记转换成任务
@degreesign/voice答案时 网络关闭. - 在设备上: 重量下载一次, 然后每个回复都是本地生成的, 没有 API 密钥, 没有每个复制成本.
- 插接并播放: 包会选择引擎, 适合提示, 恢复 下载和再利用缓存,没有设置.
- 无头和无国籍:结果通过召回,所以任何UI都可以 创建它们,并且没有保存历史;主机通过整个信件列表.
- 一次运行后的两个引擎:CPU通过wllama,WebGPU通过LiteRT-LM.
- 类型和便携式:每一份出口的申报,进口在 浏览器,工人,反应和节点.
安装
npm install @degreesign/chat
yarn add @degreesign/chat
pnpm add @degreesign/chat
引擎和助手被捆绑成动态块,所以主机解决了否
引擎只导入和下载模型使用的块。 只有模型重量
从包外而来. 建筑的发射 dist/browser/chat.min.mjs 与
其引擎块、通用JS和无害环境管理节点条目 dist/node/, 原声
资产在 dist/assets/wllama/ 财务报告和审定财务报表 dist/assets/litert/,以及 dist/index.d.ts。 。 。 .
以 yarn build键入 yarn typecheck 测试节点条目
与 yarn verify:node。 。 。 .
快开始
建立全速,呼叫 createChat,生成累积文本。 这个
调用返回一个取消函数并启动状态后的模型
调用.
import { LlmRole, clearModelCache, createChat, preloadModel } from "@degreesign/chat";
const messages = [
{ role: LlmRole.system, content: "Answer in two sentences." },
{ role: LlmRole.user, content: "Hello" },
];
// Optional: download and load the model before the first send.
await preloadModel();
const cancel = createChat({
messages,
onResponse: (text) => renderReply(text),
// onThinking, onSpeed, onPromptSpeed and onStatus are optional.
});
// Later, stop the reply, cancel the load, or free the model.
cancel();
// Delete every cached model file when the device needs the space.
await clearModelCache();
无 model 当浏览器提供一个
WebGPU适配器和没有时的CPU模型.
createChat 返回不承诺或控制器。 每一个结果都通过
onResponse,以及 onStatus 报告 requesting: false 当回复结束.
onSpeed 因此它排除了即时处理。 这个
主机附加用户和助理信件本身; 软件包从不写
存储。 用户回合可携带 images 或者说 audio; 见
快速装配。 。 。 .
公共 API
createChat(input: ChatInput): CancelChat
preloadModel(input?: ChatPreloadInput): Promise<boolean>
describeImage(input: DescribeImageInput): Promise<string>
descriptionEnhanced(input: DescriptionEnhancedInput): Promise<DescriptionEnhanced>
translateTags(input: TranslateTagsInput): Promise<ImageTag[]>
describeModelId: ChatModelId
imageReplyTokens: number
gpuAdapter(): Promise<boolean>
clearModelCache(): Promise<void>
每回复一次 新调用中止了上一流, 以及一个模型
已经装入了跳过下载和负载。 一个模特留在家里
clearModelCache 释放并删除所有缓存文件.
ChatInput数字 :
| 外地 | 说明 |
|---|---|
model? | ChatModelId ; 替换已装入的模型. |
messages | 完整的快取,包括系统消息和新用户转接. |
limits? | 部分 LlmLimits; 见下文预算缺省. |
reasoning? | 模特儿能不能先考虑一下 默认为 false。 。 。 . |
logging? | 是否写入软件包和引擎控制台日志 。 默认为 false。 。 。 . |
onThinking? | 接收累积的推理文本. |
onResponse | 接收累积的回复文本。 要求. |
onSpeed? | 以每秒符号接收当前生成速度. |
onPromptSpeed? | 以每秒符号接收活的即时处理速度 . |
onStatus? | 接收 a ChatStatusSnapshot 每一个州的变化. |
预算默认为250个回信符,128个CPU思维符,1200 GPU
推理符(CPU上320个),2个图像,1个音频剪辑,每集1000个字符
消息, 10000 个提示字符, 32 个 CPU 线程和一个完整的 GPU 繁忙共享 。 这个
CPU 引擎忽略 gpuShare; GPU 引擎在预填后应用.
CancelChat 实值 () => void数字 :
| 状态 | 效果 |
|---|---|
| 下载或加载 | 停止等待;共享下载持续进行,其字节保留. |
| 准备 | 中止回复并卸下解答的模型. |
| 旧电话 | 没什么,因为一个新来的电话 拥有运行时间. |
预装
打电话 preloadModel 第一次选举之前 createChat 提前装入。 它决定
true 当运行时间准备好了 false 当模型未知时,
不支持或失败 。 预加载没有取消功能, 所以取消聊天
让它的下载运行.
ChatPreloadInput 带 model?, (中文(简体) ), limits?, (中文(简体) ), logging? 财务报告和审定财务报表 onStatus?编辑
最后简要报告 ready: true, (中文(简体) ), phase: LlmPhase.load 财务报告和审定财务报表 percent: 100
成功与否,或 error 与 availability: ChatStatus.offline 失败.
描述一个图像
describeImage(input: DescribeImageInput): Promise<string>
用英语描述一个图像 qwen3_vl_2b_instruct中,Q4 K M 构建
Unsloth Quen3-VL 2B 指令. 描述器用特定的
术语 可见器官和肢体的生物名称 和优先级
不寻常的细节。 绝对不能说谎,使用模糊的推荐,更喜欢
或重复请求.
systemRulesOverride 替换默认的系统消息。 电话用的是
imageReplyTokens 128个符号的预算,除非 limits.maxReplyTokens
超过它,请求192 视觉标志 大小调整,和样本在
温度为0.1.
DescribeImageInput 扩展 CallOptions数字 :
| 外地 | 说明 |
|---|---|
image | 一个图像数据 URL或 URL . |
systemRulesOverride? | 替换默认描述器系统消息. |
onSpeed? | 接收生成速度, 符号每秒 . |
onText? | 接收累积的流出文本. |
承诺解决已修剪的英语描述, 或者在
模式返回无文本。 完成负载报告 percent: 100 财务报告和审定财务报表
phase: LlmPhase.load 在第一个文本之前,所以一个主机可以清除它的进展
排队.
增强描述
descriptionEnhanced(
input: DescriptionEnhancedInput,
): Promise<DescriptionEnhanced>
接受一个英文描述,当目标不是英文时翻译它,然后
从同一文本创建其画廊标记。 没有 model 覆盖, 文本
模型为 gemma4_e2b_limited 当WebGPU适配器存在时 qwen3_vl_2b
否则。 标记的通行证要三个英文单词, 然后填满目标
每个标签的语言密钥。 翻译失败或回复
CANNOT_TRANSLATE,保留英文描述。 失败的标签调用离开
标记为空; 缺少标记翻译保留了英文标记.
DescriptionEnhancedInput 扩展 CallOptions数字 :
| 外地 | 说明 |
|---|---|
descriptionEN | 需要翻译和标记的英文描述. |
targetLanguage | 提示中使用的语言名称, 如 German。 。 。 . |
targetCode | 用作标签翻译密钥的双字母代码, 例如 de。 。 。 . |
withTags? | 是否生成标记 。 默认为 true。 。 。 . |
withDescription? | 描述是否被翻译 。 默认为 true。 。 。 . |
model? | 文本模型覆盖; 包在可用时选择 GPU 构建 . |
onStage? | 接收 translate, (中文(简体) ), tags 或者说 translateTags 每次通过开始. |
onSpeed? | 接收生成速度, 符号每秒 . |
onText? | 接收已累积的流媒体文本及其舞台. |
DescriptionEnhanced 持有 description (翻译或英语)
倒计时, translated (是否正在使用目标语言), tags (至多
3个 en 和目标代码,包括 nsfw (如标出)和
nsfw? 布尔.
翻译存储标签
translateTags(input: TranslateTagsInput): Promise<ImageTag[]>
翻译一个画廊已经持有的标签, 而不描述或标记 .
每个标签都保留它 en 文字和获得 targetCode 键; 拒绝或
调用失败, 返回英文标记不变 。 文字模式也一样
规则为 descriptionEnhanced,当它已经坐落在记忆中时,它会被再利用.
TranslateTagsInput 扩展 CallOptions数字 :
| 外地 | 说明 |
|---|---|
tags | 这个 ImageTag 要翻译的列表. |
targetLanguage | 提示中使用的语言名, 如 German。 。 。 . |
targetCode | 双字母代码写作标签翻译密钥. |
model? | 文本模型覆盖; 包在可用时选择 GPU 构建 . |
onText? | 接收累积的流出文本. |
调用选项
每个描述和标签呼叫都一样 CallOptions数字 :
| 外地 | 说明 |
|---|---|
signal? | 停止通话,工作结束. |
limits? | 部分 LlmLimits 每个请求的模型调用. |
logging? | 是否写入软件包和引擎控制台日志 。 默认为 false。 。 。 . |
onStatus? | 接收 a ChatStatusSnapshot 模型装入并运行. |
onEstimate? | 接收一个 EstimateReport 在模型装入之前. |
估计数
三个职能报告持续到 onEstimate,与 totalEst 财务报告和审定财务报表
(单位:千美元) breakdown 联 合 国 operation 财务报告和审定财务报表 est 秒数. describeImage 报告
analyze 财务报告和审定财务报表 describe· ; descriptionEnhanced 报告 translate, (中文(简体) ), tags 财务报告和审定财务报表
translateTags· ; translateTags 报告 translateTags 一个人,留下一个
不运行的阶段。 测量的阶段保留在 localStorage 键
degreesign-chat-estimates-v1在那之前有一个内在倒计时.
已折旧的批次助手
describeImages 财务报告和审定财务报表 describeTranslated 保持为两边的包装
单项函数。 2027年11月以后,它们将被剥离,
当没有WebGPU适配器时跳过翻译。 使用 describeImage 财务报告和审定财务报表
descriptionEnhanced 新代码.
工具
三艘内置工具船作为描述器. 它们与模型无关: 软件包从不向引擎宣布工具,也从不自行运行.
import { builtinTools, BuiltinTool } from '@degreesign/chat';
const [calculation] = builtinTools([BuiltinTool.calculate]);
const answer = await calculation.execute({ expression: `6*7` });
| 导出 | 说明 |
|---|---|
builtinTools(names, config?) | 按给定的顺序返回请求的工具. |
calculateTool | 评估完全本地化的算术表达式. |
currencyTool | 通过CoinExams饲料在菲亚特,金属和硬币之间转换. |
webSearchTool(config?) | 默认搜索维基百科,或DuckDuckGo. |
BuiltinTool | websearch, (中文(简体) ), calculate 或者说 currency。 。 。 . |
WebSearchProvider | wikipedia 或者说 duckduckgo。 。 。 . |
每个工具都有 name, (中文(简体) ), description, (中文(简体) ), parameters (单位:千美元)ChatToolSchema和
execute(args),返回 JSON 安全 ChatToolValue 或掷出.
webSearchTool 带 provider,维基百科 language, (中文(简体) ), limit, (中文(简体) ),
snippetLength 财务报告和审定财务报表 timeout通过网络搜索和取出货币;
calculate 没有.
状态
ChatStatusSnapshot 是唯一的生命周期信号:
| 外地 | 说明 |
|---|---|
model? | 运行的模型,或者在它解决之前要求的构建. |
availability | ChatStatus.online, (中文(简体) ), .away 或者说 .offline,来源于 status。 。 。 . |
status | LlmStatus数字 : idle, (中文(简体) ), downloading, (中文(简体) ), ready, (中文(简体) ), error 或者说 unsupported。 。 。 . |
backend | LlmBackend.cpu, (中文(简体) ), .gpu 或者说 .none。 。 。 . |
supportsImages | 模型是否接受此设备上的图像 . |
supportsAudio | 模型是否接受此设备上的音频 . |
ready | 是否装入模型并接受回复 . |
loading | 无论是下载还是载荷都在飞行中. |
requesting | 回复是否正在流传中 . |
phase | LlmPhase.download 或者说 .load。 。 。 . |
percent | 下载或加载进度, 0 改为 100。 。 。 . |
error? | 最后一个失败, 答复开始后清除 . |
里面的第一幕火势同步 createChat。最后的快照
与 requesting: false 标记结束,包括取消的呼叫.
describeImage 财务报告和审定财务报表 descriptionEnhanced 报告相同的快照.
在桌面上5分钟后从未产生出第一个块的流结束
或50分钟的电话, 一个图像转动至少等待14分钟一个
慢 CPU 预填. 一旦一个块到达, 30秒的沉默结束了溪流
并保存已发送的文本。 除非接到呼叫,否则控制台输出停止
通过 logging: true。 。 。 .
模型
ChatModelId | 名称 | 理由 | 图像 | 音频 | CPU 软件 | 网络GPU |
|---|---|---|---|---|---|---|
qwen3_vl_2b | 倒数 2B | 对 | 对 | 没有 | 对 | 没有 |
qwen3_vl_2b_instruct | Quen3-VL 2B 指令 | 没有 | 对 | 没有 | 对 | 没有 |
qwen3_vl_2b_instruct_q3 | Quen3-VL 2B 指令 Q3 | 没有 | 对 | 没有 | 对 | 没有 |
gemma4_e2b_limited | Gemma 4 E2B 限制 | 对 | 没有 | 没有 | 没有 | 对 |
qwen3_vl_2b 是通用模型和视觉模型: 带有
型号,共约1.5GB,手机上4096个指使上下文或8192个
桌面。 它的投影机共享文本线程预算,因此图像会转等.
qwen3_vl_2b_instruct 是 Unsloth Q4 K M 构造的 describeImage 负载,
同为Q8 0投影仪而无推理通关;Q3 K M变体相關
160 MB 较小.
gemma4_e2b_limited 装入 2. 0 GB gemma-4-E2B-it-gpu.litertlm 带有
32768 标语上下文在桌面上,16384 手机上,没有视觉或音频
编码器。 第一次通话下载后再调用;中断
下载从最后一个承诺部分恢复.
快速装配
这个 messages 数组是整个提示。 包包将它捆绑并塑造它
用于引擎;它没有添加自身的身份、语言或任务文本.
system: {system messages, in list order}
user: {first user turn}
assistant: {next turn}
user: {next turn}
- 首席助理转会取消 连续的同作用转会合并, 并跳过空信件.
maxContentLength剪辑每个消息和promptCharBudget约束整个 即时;图像和音频有效载荷不能算在内.- 每个提示都安装在模式上下文窗口:最古老的非系统旋转 和64个按键的答复预算 以为模板预留的128个令牌封入了其余窗口.
- 系统消息被折叠成一个主系统转折.
- 图像和音频来自 最新的转弯第一,盖由
maxImages(违约2)和maxAudio(默认一). 旧部分被丢弃,文本留下. - 每个图像都保持其全帧,目标128个视觉符号,最多136个, 撕裂成32px的倍数,其余部分被收割.
- 带有文本模型报告的仅图像旋转
Model does not accept images· ; 只有音频的回合报告Model does not accept audio。 。 。 .
启用 WebGPU
请求没有 model 选择 gemma4_e2b_limited 当浏览器曝光时
WebGPU 适配器和 qwen3_vl_2b 当它没有. gpuAdapter() 运行相同
探测器,每张快照都报告运行中 model。检查前
指责软件包:
const adapter = await navigator.gpu?.requestAdapter();
adapter
? `${adapter.info.vendor} ${adapter.info.architecture}`
: `no adapter`;
null 表示API存在,但没有适配器存在. 铬报告状态
chrome://gpu数字 : WebGPU 改为 Hardware accelerated火狐列表
特性在 about:support,关于 Linux 需要 dom.webgpu.enabled 设置为
true 内 about:config。 。 。 .
Chrome, Edge和Brave飞船WebGPU在Windows, macOS和ChromeOS上. 在Linux上,
启动浏览器时使用两面旗子, 因为其中之一都返回 null数字 :
google-chrome --enable-features=Vulkan --use-angle=vulkan
--enable-unsafe-webgpu 只解锁软件适配器:读取的销售商
google 是 CPU 上的 SwiftShader 。 无头铬需要加
--enable-features=Vulkan,WebGPU 财务报告和审定财务报表 --use-angle=vulkan。 。 。 .
GPU 引擎将模型和 KV 缓存保存在 GPU 内存中, 并停留于每次后
只有当 limits.gpuShare 问取来. 默认是 1,没有
休息,卡片按全解码速率坐;从0.05降至1
在符号之间留有卡片时间,预填总是会运行未节奏. 一张繁忙的牌
可能丢失设备( c)VK_ERROR_DEVICE_LOST; 关闭其他 GPU 标签或使用
CPU型号.
发动机和资产
选择每个模型的引擎:当模型有一个时,通过LiteRT-LM的WebGPU
litert 文物和浏览器曝光 navigator.gpu 财务报告和审定财务报表 WebAssembly· ;
当模型有一个时,CPU通过wllama cpu 文物; LlmStatus.unsupported
否则,包括节点。 两者都执行 startLLM 返回时 model, (中文(简体) ),
backend, (中文(简体) ), contextSize, (中文(简体) ), chat() 财务报告和审定财务报表 unload()。 。 。 .
CPU 引擎保留了五分之一的逻辑核心自由( 至少一个) 并给出
其余的到引擎, 所以8线运行与7. limits.maxThreads 仅限
降低计数。 视道为两根胶囊,大小由
scripts/patch-wllama.cjs 在每一个建筑.
CPU 引擎对其线程需要跨源隔离:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
显示 crossOriginIsolated === true 在页面中; 不隔离引擎
回到一条线。 下 require-corp 每一个跨源子资源
必须是 CORS 允许或携带 Cross-Origin-Resource-Policy。 。 。 .
两个引擎都保留原产地私人文件系统中的可回收部件,在
wllama-store 财务报告和审定财务报表 litert-store。下载可获取32个 MB 区域,然后从
最后一个承诺字节.
包装的wllama二进制 dist/assets/wllama 和《公约》
下潜时 dist/assets/litert。将两个文件夹复制到应用程序捆绑的旁边
生产;wllama需要其同类工人。 LitERT-LM 需求
与JSPI并发的WebGPU和放松了的SIMD是被设定的特性.
节点.js
软件包在没有DOM的情况下导入和运行,所以在脚本,测试,SSR方面有效
和服务器侧管弦乐,以及快速装配、预算、状态和
取消 。 两个引擎都需要浏览器 所以 createChat 有报告
LlmStatus.unsupported 财务报告和审定财务报表 ChatStatus.offline召回者保持沉默
preloadModel 决定 false。 。 。 .
const { createChat, preloadModel, ChatModelId, LlmRole } = require("@degreesign/chat");
import { createChat, preloadModel, ChatModelId, LlmRole } from "@degreesign/chat";
require 决定 dist/node/chat.node.min.js 财务报告和审定财务报表 import 决定
dist/node/chat.node.min.mjs通过出口图.
反应
打电话 createChat 从发送处理器中保留取消函数,并
用面板卸载它。 包裹从来不碰DOM,所以是一样的
模块在安全部门改革期间制作.
import { useEffect, useRef, useState } from "react";
import { ChatModelId, LlmRole, createChat } from "@degreesign/chat";
const useReply = () => {
const cancelRef = useRef<(() => void) | null>(null);
const [reply, setReply] = useState("");
useEffect(() => () => cancelRef.current?.(), []);
const send = (history, text) => {
setReply("");
cancelRef.current = createChat({
model: ChatModelId.qwen3_vl_2b,
messages: [...history, { role: LlmRole.user, content: text }],
onResponse: setReply,
});
};
return { reply, send };
};
类型
投入是: ChatInput, (中文(简体) ), ChatPreloadInput, (中文(简体) ), DescribeImageInput, (中文(简体) ),
DescriptionEnhancedInput 财务报告和审定财务报表 TranslateTagsInput,每个图像和标签输入
发展于 CallOptions;结果为: DescriptionEnhanced, (中文(简体) ), EstimateReport
财务报告和审定财务报表 ImageTag。 。 。 . ChatMessage, (中文(简体) ), ChatStatusSnapshot, (中文(简体) ), LlmLimits, (中文(简体) ), CancelChat
财务报告和审定财务报表 WllamaAssets 描述其他类型; 已贬值类型为
DescribeImagesInput, (中文(简体) ), DescribeTranslatedInput 财务报告和审定财务报表 ImageDescription编辑
电荷是 ChatModelId, (中文(简体) ), LlmRole, (中文(简体) ), ChatStatus, (中文(简体) ), LlmStatus, (中文(简体) ), LlmBackend, (中文(简体) ),
LlmPhase, (中文(简体) ), EstimateOperation, (中文(简体) ), DescriptionEnhancedStage 财务报告和审定财务报表
ChatPreloadField。 。 。 .
测试
yarn test:instruct 用 Qune3-VL 2B 启动本地的 lama.cpp 服务器
指示 Q4 K M 以 127.0.0.1:8080,只有CPU,把重量挤到外面
存储器. yarn test:images 运行浏览器套件,然后
假引擎吊带不需要服务器. yarn verify:node 检查节点条目 .
建筑
这个 交互式地图
覆盖两个条目, 每个有行号的源模块, 助手边缘
和送货的流向。 A 类
比较 @mlc-ai/web-llm
在WebGPU上覆盖了Gemma 4 E2B.
财务问题
什么是@ 学位/ 聊天?
一个无头的推论控制器。 它装入一个模型, 流一个回复 和报告状态; 应用程序拥有聊天历史、 存储和UI, 传入 每次通话时,请立即回复.
它支持图像还是音频?
图像在视觉支持的模型上工作: 将 URL 设置在用户转弯处 images
阵列。 一个没有视力的模型,当转弯也有文字时, 就会丢掉它们
只图像翻转报告 Model does not accept images。没有目录模型
音频编码器,所以 audio 行为也一样.
它需要服务器还是运行时间依赖?
没有。 聊天,下载和推论 运行在设备,和引擎船 捆绑了,所以一个主机没有导入引擎,电线也没有对等依赖.
我选哪个模特儿?
Qune3-VL 2B 支持CPU上的推理和图像,并在任意浏览器上运行 还有WebAssembly。 Gemma 4 E2B 支持以更快的文本在 WebGPU 上进行推理, 但是 更大的下载和较慢的初次编译.
许可证发放
运行时间代码是麻省理工学院许可. 推论引擎和模型重量
由提交人按他们自己的条件分发,列于
THIRD_PARTIES.md。见 LICENSE。 。 。 .
关键词
@degreesign/chat,在线聊天 AI,本地LLM,wllama,liter,webgpu,
gemma, amm, 聊天控制器, 无头聊天, TypeScript, 浏览器, 语音
友好的答复.