# 墨白｜自然改写工作台

一个面向中文编辑和内容创作者的文章改写网站。Orion 模式复现老师软件“降低文章 AI 率”的逐行本地调用链；DeepSeek / OpenAI 模式仍提供分析、规划、成稿三阶段流程。

## 已实现

- 无需 API Key 的本地规则演示；
- DeepSeek / OpenAI 三阶段模型改写；
- 已恢复的 Orion 本地模型与老师版 LM-Kit 推理运行时，无需 API Key；
- Orion 本地预分析 + DeepSeek / OpenAI 终稿的混合模式；
- 改写幅度调节；
- Orion 老师模式按非空行调用并原样保留换行，不额外规划、删减或重排；
- 可选的结构、数字、长度、模板残留和指令复述质量门；
- 可选的结构重写模式；
- TXT、Markdown、HTML、DOCX 导入；
- 多文件批量队列；
- 原稿与新稿差异高亮；
- 新稿复制、TXT 导出；
- 原文分析与新稿规划面板；
- 响应式桌面和移动端布局。

## 本地运行

```bash
npm install
npm run dev
```

没有配置密钥时，点击“开始深度改写”会运行本地演示。点击右上角设置，可以填写 DeepSeek 或 OpenAI API Key；密钥只保存在当前浏览器会话中，并随每次请求发送给对应模型服务。

## 使用 Orion 本地模型

先在一个终端启动已恢复的模型：

```bash
npm run orion
```

再在另一个终端启动网站：

```bash
npm run dev
```

打开模型设置并选择“Orion”。网站会按老师程序的实际路径处理每个非空行：固定 ChatML 提示词，首行完整解码，后续行保留前 31 个公共提示 token，再生成下一段。改写幅度复刻为老师 6.0 的 10 个离散档位（极低、很低、低、偏低、中低、中、中高、偏高、高、极高），每档按实测表切换 `temperature`、`typical_p`、`top_p`、`min_p` 和三项重复惩罚；默认“低”档仍是 `temperature=0.65`、`top_k=1`、`typical_p=0.9`、`top_p=0.95`、`min_p=0.08`、`repeat_penalty=1.08`、`frequency_penalty=0.10`、`presence_penalty=0.10`。质量门默认关闭，模型原始结果直接展示；需要时可以在右侧手动开启。

`npm run orion` 会编译并启动智媒 6.0 专用的 `lmkit_orin_cli.c` 常驻 worker，加载 6.0 激活版自带的 `LM-Kit.llama.dylib` 和本地 `Orin-6.0.gguf`。模型只加载一次，HTTP 包装层继续提供网站现有的 `http://127.0.0.1:18080/v1/chat/completions` 接口。老师原始模式按行保留换行，并把每个非空行切成最多 80 字的小段依次改写。

如果希望效果高于 3B 本地模型，可选择 DeepSeek 或 OpenAI，并启用“用 Orion 做本地预分析”。此时 Orion 负责提取事实和模板问题，所选云模型负责最终逐段编辑。

## 验证

```bash
npm run build
npx tsc --noEmit
```

## 构建 macOS 桌面版

桌面安装包只包含界面、后台服务、Node 运行时和 LM-Kit 推理库，不包含约 1.27 GB 的模型文件。首次启动时，模型下载到：

```text
~/Library/Application Support/墨白/Models/Orin-6.0.gguf
```

构建时通过环境变量写入你自己的 HTTPS 模型下载地址：

```bash
MOBAI_MODEL_DOWNLOAD_URL="https://你的对象存储地址/Orin-6.0.gguf" npm run desktop:build
```

产物位于 `dist-desktop/墨白.app`。应用会核对模型大小 `1272736576` 字节及 SHA-256 `b934688d11c377b7f8ce6eb6591710cb8dea23a6b246f208f7ea2016efbdacfd`；校验通过后才会启动推理服务。下载地址未配置或需要离线安装时，首次启动页也可以选择已有的同一 GGUF 文件。

## 激活码与管理后台

墨白启动时会先验证机器绑定许可证；许可证通过后才检查模型并启动工作台。激活码使用 Ed25519 签名，应用包只携带公钥，签发私钥保存在独立后台数据目录。

首次初始化并启动本机管理后台：

```bash
npm run activation:init
npm run activation:admin
```

浏览器打开 `http://127.0.0.1:19090`。总管理员账号为 `admin`，密码显示在启动终端并保存在后台数据目录。分销结构为：

```text
平台总管理员 → 分销商账号 → 终端客户 → 客户机器 → 激活码记录
```

总管理员可以创建分销商、设置独立登录账号、分配或追加发码额度、冻结渠道、重置分销商密码，并查看全平台的客户、机器和签发记录。分销商登录后只会看到自己的客户、机器、激活记录和额度流水；每生成一枚激活码扣减一个额度，额度不足时停止签发。

分销商的日常流程是：

1. 使用平台分配的账号登录；
2. 在“终端客户”中添加客户；
3. 从客户列表进入“签发激活码”；
4. 输入客户端机器码、机器备注和有效期；
5. 后台自动建立分销商 → 客户 → 机器 → 激活记录关联；
6. 在“生成记录”中查询并复制历史激活码。

后台支持 30 天、90 天、1 年、2 年、永久，以及精确到日期和时间的自定义有效期。同一机器码保持唯一客户归属，同一客户可以登记多台机器，也可以为已有机器再次续期签发。升级前的数据会归入“总部直营”。全部分销、额度、客户、机器、发行记录、后台密码和签名密钥保存在 `activation-admin/data/`，该目录已从 Git 排除。

需要备份的核心文件是：

```text
activation-admin/data/license-private-key.pem
activation-admin/data/license-public-key.txt
activation-admin/data/admin-password.txt
activation-admin/data/distributors.json
activation-admin/data/quota-ledger.json
activation-admin/data/users.json
activation-admin/data/machines.json
activation-admin/data/licenses.json
```

同一套已发行激活码依赖同一对签名密钥。更换私钥后，需要用新公钥重新构建应用，并重新签发激活码。客户端会在每次启动时验证到期时间，运行期间每 60 秒复查一次；许可证到期后会停止由墨白启动的本地服务并返回激活页。

演示模式只用于体验界面与流程，不代表真实模型质量。改写结果仍需人工核对事实、数字、引用和发布语气。本项目不保证规避或通过任何第三方检测。
