一只能把 LLM 整理文档的输出反向追溯回原文证据的桌面小助手。
给中文机关 / 央国企 / 律所 / 编辑部 / 学术写作场景用的可解释 LLM 工作流。
English README · 架构文档 · 离线模型指南 · 隐私声明 · 更新日志
Fork & 致谢:Nuki 在 OpenPets 的 Electron 桌宠骨架上派生而来,并在其之上重写、新增了围绕"中文机关办公文书 + 可解释 LLM 工作流"的若干模块。详见
NOTICE。协议:MIT(详见
LICENSE)。关于商用:如果你打算把 Nuki 整体或其 trace / claim verify / conflict detect 等核心模块用于商业产品、SaaS、政企招投标,恳请先在 Issues 留言或邮件告知(rui.li.buaa@gmail.com)。这只是道义请求,不创设额外法律义务,但作者会很感激,也乐于与认真做事的团队交流。
⚠️ v0.1.0-alpha 阶段说明这是 Nuki 首个对外预览版本。下文描述的 5 个 office agent / 句子级 claim verify / 跨源 conflict detect / Watcher 框架 在作者本机 + 云端 API(DeepSeek / Qwen / OpenAI)跑通,并有 10 个 smoke 测试覆盖结构断言;但尚未经过大规模真实数据的端到端验证,不要按"稳定生产工具"的预期使用。
已知不稳定点详见 CHANGELOG.md Known issues。简要:
- claim verify 的命中率强依赖模型能力,7B 离线模型下
unsupported误报会偏高- conflict detect 基于 bigram 分桶,措辞差异大的真冲突可能漏检
- Watcher 崩溃恢复 / cron 边界情况只做了最常见路径的处理
- 编辑回滚 ⌘Z 只在单个 agent 窗口内有效,不跨窗口
- 桌面端打包未做代码签名,详见下文"打包"段
真正稳定的 GA 版本会等社区反馈一轮后再发 v0.1.1 / v0.2。
把市面上的 LLM 整理文档工具拍扁,大多长这样:
用户原文 → LLM → 一段看着像样的总结 → 用户看着就信了
Nuki 不这么做。Nuki 长这样:
用户原文 → 切段([P1]…[Pn]) → 主 LLM 输出 + 反向引用 → 二次 LLM 抽 claim
→ 二次 LLM 逐条核查
→ 三次 LLM 跨文件比对
┌─ 主输出(带引用 chip,点击跳原文)
├─ verdict tag(每句"原文支持 / 未提及 / 与原文矛盾")
├─ 冲突高亮(多文件互相打架的句子下红波浪 + 悬浮卡)
└─ 编辑模式(改一句立刻重对齐,撤回栈 ⌘Z)
你看得见 LLM 在哪里编的、哪里漏的、两份材料哪里对不上。
| Agent | 输入 | 主输出 | 反向追溯 |
|---|---|---|---|
| foreign-summary | 外文 PDF / 长文 | 中文要点 bullet(5-10 条) | 每个 bullet 挂 [P#] 段落引用 + verdict |
| meeting | 会议口语化笔记 | 议题 / 决议 / 行动项三栏 | 每条挂 [P#] + 责任人/截止日期校验 + verdict |
| doc | 中文稿件原文 | 润色稿 / 缩写 / 扩写 + 红队复审 | 句子级 ↔ 段落映射,红队 banner 高亮"立场过强" / "数据未引" |
| folder-report | 一个文件夹 | 多文件综合报告(带 [F#] 文件引用) | 跨文件 冲突检测:行内红波浪 + 悬浮卡 + 跳源 |
| ppt-outline | 主题 | 10-15 张幻灯片大纲(每页 title + 3-5 bullet) | — |
每个 agent 都遵守同一组工程约束(见 架构文档):
- 主 LLM 输出必须挂
paragraphIds: number[]引注 - 二次
extractClaims+verifyClaimspass 标 supported / unsupported / contradicted - 渲染层有"编辑回滚"工具,改字 → 触发
realignIPC → chip 更新或灰掉 - 所有结构化 LLM 调用走
chatStructured:JSON 失败自动重试一次(温度减半),再失败降级,记 audit
5 个 office agent 解决的是"我手上有材料,帮我整理一下"。Watchers 解决的是 "有些事我想让 Nuki 定时帮我盯着,命中再喊我"。
抽象成 4 件事:
Trigger → Source → Summarizer → Alert
(何时跑) (拉什么) (LLM 怎么整) (什么情况通知)
- Trigger:
cron(5 字段,自带 parser)/interval(每 N 分钟)/manual - Source:
http(带 30s 超时 + 1MB 上限 + 可选 HTML 剥标签)/rss(迷你 RSS / Atom 解析器)/prompt(无外部源,纯 LLM) - Summarizer:你写的 prompt + 期望 JSON schema,按域注入安全 footer(
stock域禁"建议买入/卖出/推荐/看多/看空/目标价") - Alert:
always/verdict(verify pass 不通过才报)/threshold(如papers[*].importance >= 4)/silent(仅落库)
通知只走桌宠气泡 + 系统通知;不做 email / IM push("做不好就别做"原则)。命中后桌宠气泡有"查看"按钮,跳独立的 Watcher 历史窗口。
内置 3 个模板,开箱即用:
| 模板 | 干什么 |
|---|---|
| arxiv RSS | 每天早上拉指定 arxiv 分类,按你的研究方向打分 + 摘要 |
| RSS 新闻 | 通用 RSS 聚合,按你定义的关键词 / 主题筛选 + 中文摘要 |
| 雅思口语 | 每天给你一道 Part 2 题 + 关键词 + 范文骨架 |
不内置股票实时行情 source:Tushare 免费档不够;自己接 Sina / EastMoney / Yahoo HTTP 源完全可行,但 v0.1 不官方提供。
崩溃 / 重启时:cron 跳过错过的槽位,interval 5 秒内补打一次,不会"突然刷出半年前的 100 条"。
桌宠点开即聊。支持多轮对话和拖入文档(PDF / DOCX / XLSX / TXT / MD / CSV / JSON / HTML 等)。
- 多轮:renderer 内存维护 user/assistant 历史,每轮一并发给 LLM;关窗即清,不落盘。需要重置点头部「清空对话」。
- 附件 = 一轮一次:文档随它被拖入的那一轮发送,后续追问看上一轮 assistant 回复里的概述。需要再次引用全文请重新拖入。
- 长度上限(防止 7B 本地模型上下文炸窗):
- 单文件 ≤ 24,000 字符(≈ 12k 中文 token)。超限当场拒绝,请改用
doc/foreign-summary/folder-report这些专门处理长文档的 agent。 - 单次输入 ≤ 8,000 字。
- 单轮附件累计 ≤ 40,000 字。
- 单文件 ≤ 24,000 字符(≈ 12k 中文 token)。超限当场拒绝,请改用
git clone https://github.com/Ray-RP/Nuki.git
cd Nuki
npm install需要 Node ≥ 20。
国内 / 公司内网装不动?
npm install会触发 Electron 二进制下载(~80MB,默认从 GitHub Releases 拉),如果 GitHub 连不上或速度极慢,改用国内镜像:ELECTRON_MIRROR=https://registry.npmmirror.com/-/binary/electron/ \ npm install或在用户全局
~/.npmrc里加一行electron_mirror=https://registry.npmmirror.com/-/binary/electron/,之后所有 Electron 项目都走镜像。
启动后桌宠从右下角出现,点开 → ⚙ 齿轮:
| 字段 | 说明 |
|---|---|
| Base URL | 任何 OpenAI 兼容地址 |
| API Key | 对应 provider 的 key(Ollama 填任意非空字符串) |
| Model | 模型名 |
支持的 provider:
| Provider | Base URL | 备注 |
|---|---|---|
| OpenAI | https://api.openai.com/v1 |
|
| DeepSeek | https://api.deepseek.com/v1 |
中文质量好,便宜 |
| 通义千问 | https://dashscope.aliyuncs.com/compatible-mode/v1 |
|
| Ollama(本地) | http://localhost:11434/v1 |
数据不出电脑 |
| OpenRouter | https://openrouter.ai/api/v1 |
多模型聚合 |
推荐离线模型:Qwen2.5-7B-Instruct (q4_K_M)。详见 docs/offline-models.md。
npm run devdev 监听 TS 和静态资源;主进程改动自动重启 Electron,渲染层改动按 Cmd/Ctrl+R。npm run dev:once 单次启动不监听。
npm run package产物在 release/。macOS DMG / Windows NSIS / Linux AppImage。
关于代码签名(v0.1.0-alpha)
当前发布的安装包未做代码签名 / 公证——作者还没有 Apple Developer ID 与 Windows Authenticode 证书。这意味着:
- macOS:双击 DMG 会被 Gatekeeper 拦下,提示"无法打开,因为无法验证开发者"。 解决方法:右键应用 → 打开 → 在弹窗里再点"打开";或在「系统设置 → 隐私与安全性」 底部点"仍要打开"。也可以在终端执行
xattr -dr com.apple.quarantine /Applications/Nuki.app。- Windows:SmartScreen 会显示蓝色拦截窗口,点"更多信息" → "仍要运行"即可。
- Linux AppImage:不受影响。
这是 alpha 阶段的已知限制;正式 v0.1.x 发布时会评估签名方案。源码 100% 公开, 不放心的话强烈建议从源码自行
npm run package。
| 为什么不用 | |
|---|---|
| React / Vue | 桌宠只需要薄薄一层 UI;引大库会拉高启动时间和 RAM |
| 向量数据库 / RAG 框架 | folder-report 用 bigram + 关键词分桶就够,向量库给离线用户增加部署负担 |
| LangChain / LlamaIndex | trace / verify / conflict 都是 100 行内的纯 prompt 工作,框架反而碍事 |
| Telemetry / 上报 | 机关用户最忌讳 |
| SaaS 部署 | 这是个桌面工具,不准备做 SaaS |
更详细的拒绝列表 → docs/architecture.md。
npm run typecheck # tsc --noEmit
npm run smoke # 10 个 smoke 全跑
npm run smoke:claims # 单个跑
npm run build # 生产构建
npm run package # electron-builder 打安装包CI 在 GitHub Actions 上跑(ubuntu / macOS / windows × Node 20),见 .github/workflows/ci.yml。
新增一个 office agent 的标准动作 → CONTRIBUTING.md。
- 所有 LLM 调用直接打你配的 Base URL;Nuki 不做任何中转
- 用户原文 / API key 不写入 audit 日志(audit 只记调用元数据 + verdict)
- 默认无任何 telemetry / 上报
- 完整数据流 →
docs/privacy.md
欢迎 PR:
- 读
CONTRIBUTING.md - 改 prompt 必须贴 before/after 输出对比
- 改了 IPC 形状 → preload 白名单同步改 + 更新
docs/architecture.md - 安全相关 → 邮件
rui.li.buaa@gmail.com(见SECURITY.md) - 大 PR(>100 行)建议先在 issue 讨论
签 CLA:在 PR 描述里加一行 我同意 Nuki 贡献者协议(CLA.md)。详见 CLA.md。
Nuki 新增模块的版权属于贡献者各自所有,统一按 MIT 发布。详见 NOTICE。
- Issues:技术问题 + bug + 模型反馈 → GitHub Issues
- Discussions:使用问题 + 路线图讨论 → GitHub Discussions
- 邮件:rui.li.buaa@gmail.com(安全 + 商用咨询)