Import Human Voice Rewrite Demo (PRD v1.1) + Dockerfile for Coolify

This commit is contained in:
Jeamee
2026-08-24 16:49:57 +08:00
commit d6f70b02f4
16 changed files with 3580 additions and 0 deletions
@@ -0,0 +1,103 @@
# Human Voice Rewrite Demo — 使用说明(给接手同事)
这是一个**可以自己改、自己调**的独立 Demo:前端(单页 HTML+ 后端(FastAPI+ 真实
OpenRouter 大模型调用。产品逻辑按《Human_Voice_Rewrite_PRD_v1.1》实现:AI 读懂与诊断 →
顾问人工重写 → AI 全文复检与精准返工。前台外观对齐 v6 Core Color Match 两栏原型。
## 一、快速启动
环境要求:本机有 Python 3.10+macOS 一般自带;Windows 到 python.org 安装并勾选
Add to PATH)。
**macOS / Linux**
```bash
./local_start.sh # 若提示无执行权限,先 chmod +x local_start.sh
```
**Windows**:双击 `start.bat`(或在 cmd / PowerShell 里运行 `start.bat`)。
> ⚠️ **必须用上面的启动脚本启动,不要直接运行 `uvicorn main:app`**
> 脚本负责从 `.env` 把 OpenRouter Key 导出到环境变量。直接跑 uvicorn 服务虽然能起来
> (健康检查正常),但所有 AI 调用会报「分析失败:缺少 OpenRouter Key」。
首次运行会自动创建 `.venv` 并安装依赖(需要联网)。看到
`Human Voice Rewrite Demo: http://127.0.0.1:8000` 后,浏览器打开该地址即可。
- Key 已内置在本目录 `.env`(从公司后端环境变量导出,见第五节保密提醒)
- 端口冲突:macOS/Linux 用 `HVR_PORT=8001 ./local_start.sh`Windows 先
`set HVR_PORT=8001`PowerShell 用 `$env:HVR_PORT=8001`)再运行 `start.bat`
- 停止:终端 `Ctrl+C`
## 二、目录结构
| 文件 | 作用 | 同事常改的点 |
|---|---|---|
| `index.html` | 前端单页(两栏 Workbench、聚焦/全文、批注、调后端 API) | 示例文书 `SAMPLE_ESSAY`、示例题目 `SAMPLE_PROMPT`、页面文案 |
| `main.py` | FastAPI 入口与五个业务端点 | 一般不动 |
| `prompts.py` | **AI 提示词**(分析/诊断/复检/写作起点/参考片段)+ Pattern 库 | **调 AI 行为和输出质量主要改这里** |
| `llm.py` | OpenRouter 客户端(模型、温度、超时、重试) | 模型默认值 `DEFAULT_MODEL``temperature``max_tokens` |
| `schemas.py` | 前后端接口数据结构(对齐 PRD v1.1 §31) | 增删字段时前后端同步改 |
| `evidence.py` | Pattern / Annotation 证据核对(原文命不中则不画高亮) | 一般不动 |
| `local_start.sh` / `start.bat` | 一键启动(建 venv、读 .env、起服务) | 端口、env 路径 |
| `.env` | OpenRouter Key + 代理地址 | **换 Key / 换代理在这里** |
| `test_demo.py` | 离线测试(不消耗模型调用) | 改了逻辑后跑 `.venv/bin/pytest` |
| `README.md` | 项目说明 | — |
## 三、三阶段业务流(真实模型)
1. **文章理解** `POST /api/analyze`:全文理解 + 每段中文理解 + 语义锚点(PRD §31.1)
2. **人味诊断** `POST /api/diagnose`:命中 P01P12 + 每段 Rewrite Direction / Inline
Annotation / Context Hint / ScaffoldPRD §31.2);顾问在对话里补充的理解和约束优先
3. **全文复检** `POST /api/recheck`:六维度验收,通过即结束;需返工只返回一个段落 + 单一
返工目标,并绑定 `rewrite_version`PRD §31.3);`/api/scaffold``/api/reference`
只在顾问主动展开时使用,并写入 exposure 记录
前端流程:进入页(可粘贴自己的文章,自动分段)→ 开始分析 → 对话确认/纠偏 → 诊断 →
两栏逐段手写(左原文+批注,右安静写作区)→ 提交复检。段落数量按实际 `1N` 动态渲染。
## 四、可以调什么(按频率)
| 想调什么 | 改哪里 |
|---|---|
| 换模型 | `llm.py``DEFAULT_MODEL`,或启动前 `export HVR_LLM_MODEL=别的模型` |
| 输出更稳/更发散 | `llm.py``temperature`(默认 0.3)、`max_tokens`(默认 16000 |
| 复检更严/更松 | `prompts.py``build_recheck_prompt`High Precision 规则在系统提示里) |
| Pattern 判定行为 | `prompts.py``PATTERN_LIBRARY`(P01–P12 定义 + 改写动作) |
| 示例文书/题目 | `index.html` 顶部的 `SAMPLE_ESSAY` / `SAMPLE_PROMPT` |
| 接口字段 | `schemas.py`(改后 `index.html` 里对应渲染处同步) |
| 重试/超时 | `llm.py` `complete_json`(任何失败自动重试 1 次)与 `timeout` |
改完重启服务即可生效(后端代码改动重启启动脚本;纯前端改 `index.html` 直接刷新页面)。
## 五、Key 与保密提醒(重要)
- `.env` 内是**公司真实 OpenRouter Key**(含区域代理地址),已随包分发,仅限内部使用:
- 不要把整个文件夹/压缩包发到外网、公开仓库、微信群外;
- 同事间拷贝前先确认接收人是内部人员;
- 若怀疑泄露,请更换 `prodream_backend/.env` 里的
`PRODREAM_BACKEND_OPENROUTER_API_KEY` 并同步更新本包 `.env`
- 本目录在仓库里是 gitignored 的,不会误提交。
## 六、常见问题
| 现象 | 处理 |
|---|---|
| `错误:找不到环境变量文件` | 本目录缺 `.env`,或设置了 `HVR_BACKEND_ENV` 指向了不存在的文件 |
| 服务能启动、健康检查正常,但分析时报`分析失败:缺少 OpenRouter Key` | 没用启动脚本,直接跑了 `uvicorn main:app`。用 `start.bat` / `local_start.sh` 启动(脚本负责从 `.env` 导出 Key 到环境变量) |
| 端口被占用 | `HVR_PORT=8001 ./local_start.sh`Windows 先 `set HVR_PORT=8001` |
| 分析时报 `调用大模型失败(HTTP …)` | 看错误后半段:Key 失效→换 `.env`403→代理问题(检查 `.env` 的代理地址);超时→网络 |
| `模型未返回内容(可能被截断或拒绝)` | 已自动重试 1 次仍失败,多半是网络抖动,点页面「重试」即可 |
| 页面空白 | 确认是从 `http://127.0.0.1:8000` 访问(不是直接双击 index.html,那样没有后端) |
| 想完全不用代理直连 | 把 `.env``PRODREAM_BACKEND_OPENROUTER_PROXY_URL` 那行删掉(国内网络可能不通) |
| 右侧显示「已保存」 | 只表示草稿已持久化,不等于这段已经改完,也不等于 AI 通过 |
## 七、V1.1 不要再按旧 Demo 理解的几点
- Workbench 是两栏,不再有独立第三栏 Writing Coach
- `已保存``已改写`;提交复检只看各段 `rewrite_text` 是否非空
- 段落导航和进度必须按实际段数动态生成,不能写死 4 段
- Recheck 检查的是提交时的 Snapshot;提交后继续改会进入新版本
- 只有顾问真正展开过的 Scaffold / Reference 才会进入复制检测
- 分析中(AI 初审 / 诊断 / 复检进行中)在对话页输入框输入并点发送:输入框内显示红色「AI 分析中,请稍候…」,已输入文本不清除(可继续输入,发送会被拦截,不会丢字)
- 刷新位置规则:改写进行中刷新 → 回 Workbench(改写与进度保留);理解/诊断结果态刷新 → 回对话页(历史卡完整);复检结果已返回(pass 卡/返工卡在对话页)刷新 → 停留对话页;只有复检请求进行中刷新才回 Workbench(可重新提交复检)