Liyuan 梨园 — 仓库研究综述(待验证版本 / awaiting promotion)¶
状态:agent-verified, awaiting human confirmation
研究对象:weidu12123/Liyuan @ commitf7b06e414abff4afb0651c8441db1268156ad318(HEAD ofmaster, 2026-08-09)
许可证:PolyForm Noncommercial 1.0.0 — 禁止商业用途
体量:~468K 代码行(cloc 总),TypeScript 占 58%;领域代码仅 ~16K LOC,其余是 fork 自 pi 的内核 + Vite 前端
1. 一句话定位¶
梨园是面向 AI 角色扮演的 agent 化客户端:把 fork 来的 pi (v0.80.3, 冻结) 当 agent 内核,在 harness 层(不依赖提示词)做结构化上下文裁剪(53–63% 节省每拍)、分轮演出引擎(不一次性写完,每段思考+评估+重拟)、询问接入(ask 工具让用户实时决定剧情岔路)和SillyTavern 数据生态兼容(角色卡 / 世界书 / jsonl 旧档 / 正则脚本 / 预设);同时提供一个无鉴权的本地 Web 服务(默认 7620 端口)。
2. 顶层结构(事实,固定 commit)¶
weidu12123/Liyuan/ @ f7b06e414abff4afb
├── src/ # 领域层 (纯 TS, 9381 LOC) — 心
│ ├── stage/ # 台上引擎 (4423 LOC)
│ │ ├── engine.ts (1664) # RP 原生回合循环 + agentLoop
│ │ ├── assemble.ts ( 607) # system/每拍 prompt 装配
│ │ ├── workspace.ts ( 609) # 一拍工作区: 稿/写侧执行器
│ │ ├── tools.ts ( 311) # 读写工具 schema
│ │ ├── materials.ts ( 304) # 拆层后内容装配
│ │ ├── compact.ts ( 209) # 自动压缩
│ │ ├── media-stage.ts ( 254) # 媒体阶段
│ │ ├── mcp-stage.ts ( 149) # MCP 阶段
│ │ ├── scribe-run.ts ( 105) # 场记 (旁侧模型)
│ │ ├── assistant-stage.ts ( 116) # 助手侧
│ │ └── revise.ts ( 95) # legacy #revise
│ ├── tools/ (1452) # 统一工具层 (M-D 地基)
│ │ ├── lore.ts panels.ts memory.ts card.ts worldline.ts
│ │ ├── gate.ts registry.ts adapters/stage.ts
│ ├── memory/ (1253) # 长期记忆 / 向量库
│ ├── lorebook.ts # SillyTavern 世界书解析 + 常驻注入
│ ├── card.ts # PNG/JSON 卡解析 (内嵌世界书)
│ ├── cardfront.ts # 卡正面 + 状态栏格式
│ ├── chatlog.ts # jsonl 旧档导入
│ ├── state.ts # 旁侧世界账本 (按 canonical character key)
│ ├── preset.ts # 预设 / preset-split / preset-macro
│ ├── protocol-detect.ts # 外部插件协议退场 (MVU 等)
│ ├── worldline.ts # 存档 / 回档 / 分支 (数据模型 + 落盘)
│ ├── scribe.ts # 旁侧模型落盘
│ ├── panels.ts # AI 自建面板
│ ├── tts.ts # 语音
│ ├── uploads.ts media-paths.ts
│ ├── draft.ts # 稿纸/校验/draft_check/字数/禁词
│ ├── activity-format.ts activity-format access.ts commands.ts
│ ├── agent-config.ts agent-host... (config 模型 key)
│ ├── codex.ts codex-front... (知识库)
│ ├── skills.ts samplers.ts stance.ts jsonio.ts paths.ts update.ts
│ └── stagehand.ts ziplite.ts typebox ...
├── .liyuan/extensions/roleplay.ts # 接线层 (server/ 与 pi API 唯一接触点)
├── server/ # Web 服务 + WS wire (8685 LOC)
│ ├── main.ts (2856) # HTTP + WS + pi runtime
│ ├── rest.ts (3522) # REST API + 静态托管
│ ├── assistant.ts (1524) # 助手侧独立会话
│ ├── wire.ts ( 752) # 自有 wire 协议 (零 pi import)
│ └── mcp/ # 内部 MCP server
├── web/ # Vite + React 前端 (3.3 MB)
├── packages/ # 本地依赖
│ ├── coding-agent (22 MB) # ★ fork 自 [pi v0.80.3](https://github.com/earendil-works/pi) (MIT, 冻结)
│ ├── ai (9.9 MB) # fork 自 pi ai 包 (模型目录 + providers)
│ └── tui # fork 自 pi tui (服务端未直接用)
├── packages.lock.json / package.json
│ # dependencies: @liyuan/agent-runtime, @liyuan/ai (file:), ws, @modelcontextprotocol/sdk
├── docs/ # 大量流程文档 (2.1 MB)
│ ├── PLAN-ROUND-FLOW.md (293) # ★ 分轮演出流程定义 (8/08 定稿)
│ ├── PLAN-RP-AGENT-EXEC.md (442) # ★ M-A/M-B/M-C/M-D 四里程碑执行
│ ├── PRESET-SPLIT-TAXONOMY.md # 九性质五去向类型学
│ ├── PLAN-RP-AGENT/HARNESS/TOOLING/TOOLS-PROPOSAL.md
│ ├── READING-THINKING.md # 读思考记录的正确方法
│ ├── RELEASE-v1.0.1 ... v1.3.0.md (11 份 release notes)
│ ├── REVIEW-ROUND-FLOW-0809.md st-ux-inventory.md
│ └── superpowers/ # 强化技能
├── assets/ # 默认世界书 / 卡 / 预设 / lorebooks
│ └── lorebooks/模拟修仙2.json (含 MVU 协议条 → protocol-detect 退场)
├── test/ # 56 个领域测试 (当前 577 绿)
├── deploy/ start.bat start.sh start.command docker-compose.yml
├── liyuan.agent.example.json + liyuan.config.example.json (本地配置文件, 不提交)
└── README.md AGENTS.md TESTING.md LICENSE
证据:README.md、docs/PLAN-RP-AGENT-EXEC.md、package.json、LICENSE。
3. 真正核心:四个里程碑(M-A/M-B/M-C/M-D)¶
证据:
docs/PLAN-RP-AGENT-EXEC.md§1-5、docs/PLAN-ROUND-FLOW.md、docs/PRESET-SPLIT-TAXONOMY.md、src/stage/engine.ts、src/stage/workspace.ts。
梨园不是一次性写完的项目,而是 8 周内由 4 个有明确 KPI 的里程碑迭代出来的产品(v1.0.0 2026-06-30 → v1.3.0 2026-08-09)。每个里程碑都有实测数据 + 验收门禁——这是项目最值得关注的工程纪律。
3.1 M-A:台上工作区 + agentLoop(已交付)¶
src/stage/workspace.ts——一拍一个 workspace:draft/writes/patches/lastReportsrc/stage/engine.ts——重写#toolsTurn→#agentLoop:谢幕条件、12 → 20 rounds、空正文拍结构性消灭src/stage/tools.ts——新增writeTools(language)写侧三件:draft_write / draft_check / world_state_update- 验收:f1=41951 字 → f1=8469 字(落树正文),格式栈 58% → 0%
3.2 M-B:draft_edit / read / search(已交付)¶
src/draft.ts——locateEdit(精确→trim→中文标点归一,回报命中级别)、applyDraftEdits(原子批量)、searchDraft(±24 字上下文,≤8 处)- 验收:非首拍思考量 20215 → 4748(−77%);f2 出现「查现稿→定点改 1 处→验收通过」Grep→Edit 链;首拍方差仍大
- 最大发现:MVU(酒馆
UpdateVariable/<Analysis>协议)冲突——预设「必须输出」vs draft_write「纯剧情文字」互斥,每拍烧 ~30% 思考 + 双份记账
3.3 M-C:预设拆层(已交付)——本项目的灵魂¶
- 九性质五去向类型学(A 破限 / B 全程文风 / C 行为规则 / D 通用方法论 / E 场景专题包 / F 机械纪律 / G 验算指令 / H 脑内 harness / I 噪声),见
docs/PRESET-SPLIT-TAXONOMY.md - 三份内置预设逐块手工拆层:TGbreak V2.1.6(46 启用/11517 字)、双人成行 v10.0(70/19810)、夏瑾 v2.01(12/4293)
- 常驻削减 74–83%(H 类脑内 harness 整体退场 ~14k 字)
- 新增读侧第四件工具
writing_guide(topic)——D/E 类按主题分包,按需读取(用完即走) - 验收:TGbreak 常驻 2229 / 双人 3254 / 夏瑾 720 —— 全部命中 TAXONOMY 预算
3.4 M-D:全盘工具化(已交付 3 / 4 子项)¶
- M-D1:地基 + lorebook_search 垂直切片(464 绿)
- M-D2:世界书族 lorebook_write/list/toggle +
gate.ts写入门禁(475 绿) - M-D3:向量库族 memory_search/add/list/delete +
MemoryScope助手面(492 绿) - M-D6 待办:路由破口 ——
/reroll <带参>绕过宿主拦截落到 pi 裸 LLM 回合(无台上装配),用户定案归 D 全做完后统一修
4. 当前最关键模块:分轮演出引擎¶
证据:
docs/PLAN-ROUND-FLOW.md(2026-08-08 定稿)、src/stage/engine.ts(1664 LOC)、src/stage/workspace.ts(609 LOC)、src/stage/assemble.ts(607 LOC)、src/stage/tools.ts(311 LOC)、server/main.ts。
4.1 一拍流程(每条用户消息)¶
第 1 轮:规划(读题 → 判型 → 列路标 ≤60 字/条;不许出现正文)
└─ 命中「必须问」→ ask 用户 → 答案改道 → 重拟 beat_plan
演段轮循环:
演一段(draft_append)
→ 回看刚写的(新上文到手)
→ 评估原计划:还剩的几步还成立吗?
├─ 成立 → beat_step_done 勾掉刚演的这条,演下一条
├─ 不成立 → beat_plan 重拟剩下几步,按新的演
└─ 剧情到岔路 → ask 用户 → 答案改道 → 重拟 → 继续演
收尾轮:
- 收笔条件是「戏自然演到停点」,不是「清单勾完」
- draft_seal → 全量验收(此刻才报字数)→ draft_edit 改(可多轮)
→ world_state_update 记账 → 全绿且账已记 → 上屏
4.2 关键设计¶
- 思考是演员,稿纸是表演,验收是机器 ——三层分工
- 每拍注入 vs 常驻层分离:常驻层放身份/语气/纪律(字节稳定);每拍注入放轮次卡(规划卡/开工切换卡/演段回看卡/收场卡)——对齐 opencode plan-mode/build-switch 仪式
- 硬件级门禁——同轮连发
draft_append被拒收(不是提示词提醒):一轮生成里只允许演一段,强制模型停下思考、下一次生成再落笔 - 同 round 多轮机制——
src/stage/engine.ts#agentLoop,MAX_ROUNDS = 20(v1.3.0 由 12 → 20,见#5058d15)
4.3 ask 工具(v1.3.0 新增)¶
- 三种触发(v1.3.0):
- 主动触发:用户输入触发
- 变量触发:未定变量动态衡量,严重影响剧情时触发
- 末尾触发:续写触发
- 判据:此刻不定下来剧情就走不下去(不是「新不新、重不重要」)
- 接入位置:每段之间的常态介入点 + 重点是规划轮
- 实现:
src/stage/tools.tsschema +src/stage/engine.tsagentLoop 路由 +server/main.ts注入 askChoice
5. 架构不变量(来自工程实践,不是文档理想)¶
| 不变量 | 来源 | 风险路径 |
|---|---|---|
| 正文本为模型的原始输出 | README「已知边界」第 5 条 | 试图用代码改写正文 |
| harness 而非 prompt 保证确定性 | PLAN-RP-AGENT-EXEC D2(宽进严出) | 把判断/分支交给 prompt |
| 工作区状态只活在引擎单拍内,不跨模块共享 | §2.5 jiti 二象性红线 | 触碰 globalThis 桥 |
| 落树语义 = 定稿原样 | §2.3 / M-C §4.2.7 | 抓 raw 流拼接 |
| 改字前先 grep / search 再 edit(不是脑内排练) | §2.3 / M-B | 一次性写完 |
| H 类「脑内 harness」整体退场(梨园原生机制覆盖) | TAXONOMY §1 | 让预设机制模拟引擎 |
| 内容拆分到 5 去向:A/B/C 常驻、D/E skill 按需、F 代码、G 丢弃、H 退场 | TAXONOMY §1 | 把方法论塞进常驻 |
| 模型不在状态栏格式上博弈(harness 自动追加占位符) | §4.5 状态栏根治法 | 让模型生成 <X/> 自闭合标签 |
| wire 协议与 pi 解耦(鸭子类型访问 AgentMessage) | server/wire.ts D3 | 让前端 wire 协议依赖 pi |
| 角色卡 / 世界书 / jsonl 旧档 / 预设 —— 数据生态双向兼容(不复制 ST 代码) | README 兼容性节 | 搬运酒馆代码 |
| PolyForm Noncommercial 1.0.0 —— 个人/非商业可自由;商业授权另议 | LICENSE | 倒卖/收费分发/付费托管 |
| pi fork 冻结在 v0.80.3,保留 MIT 版权 | packages/coding-agent/CHANGELOG.md / README §许可证 | 升级 fork 时不审 license |
6. 启动 / 分发链路¶
git clone https://github.com/weidu12123/Liyuan.git && cd Liyuan
cp liyuan.agent.example.json liyuan.agent.json # 填 apiKey
cp liyuan.config.example.json liyuan.config.json # 角色卡/世界书
npm install
npm run web:build # 首次或前端改动
npm run web # 起服务(默认 7620)
# 服务器部署(三种方式,详见 deploy/README.md)
# A) 一键 systemd
curl -fsSL https://raw.githubusercontent.com/weidu12123/Liyuan/v1.0.0/deploy/install.sh | bash
# B) Docker Compose(数据全在卷里)
docker compose up -d --build
# C) 手动打包(Windows)
powershell -File scripts/pack-for-linux.ps1
- Node.js ≥ 22(package.json 没显式声明但 README 与 start.sh 强要求)
- 默认端口 7620;README「请勿把 7620 端口裸暴露公网——服务本身无鉴权」
- 跨平台启动:start.bat (Windows) / start.sh (Linux/macOS) / start.command (macOS 双击)
- 配置分两份:
liyuan.config.json(角色卡/世界书/身份)/liyuan.agent.json(模型与 Key,勿提交);旧版.rp-*启动时自动迁移 - 三个发布包:Windows / Linux / macOS zip + SHA256SUMS.txt;Docker 走 docker-compose
7. 关键演进时间线¶
取自
git log --oneline(84 commits,200 深度内)+ 11 份 release notes + 流程文档;本节只列作者或文档明确记录的里程碑。
| 阶段 | 关键 commit / 文档 | 节点 |
|---|---|---|
| 2026-06-30 | fork pi v0.80.3(packages/coding-agent/CHANGELOG.md) | 内核基线 |
| 2026-07-XX | v1.0.0 → v1.0.4 | 初始 RP 客户端 + 基本 ST 兼容 |
| 2026-07-XX | v1.1.0(变量引擎 / setvar / getvar)+ v1.1.1/v1.1.2 | 预设变量宏 |
| 2026-07-XX | v1.2.0(台上外设重接 + 回合时间线 + 程序卡垫片,541 绿) | M-A/M-B/M-C 阶段产物 |
| 2026-07-XX | v1.2.1(内部文档不再随包发布;bump) | 工程清理 |
| 2026-08-03 | docs/PLAN-RP-AGENT-EXEC.md(4 里程碑执行计划定稿) | 思考塌缩问题立项 |
| 2026-08-03 | feat: RP agent 化全链竣工(M-A→M-D,492 绿) | 全链路首次贯通 |
| 2026-08-03→04 | M-B / M-C / M-C2 实施(492 → 577 绿) | 预设拆层 + MVU 通解 |
| 2026-08-08 | docs/PLAN-ROUND-FLOW.md(分轮演出流程定义定稿) | RP 流程设计靶子 |
| 2026-08-08 | feat(stage): 分轮演出流程落地 —— 注入层轮次卡 + 演段轮门禁 + ask 接回(564 绿) | v1.3.0 核心 |
| 2026-08-08 | docs/READING-THINKING.md(防 mtime 误读旧思考) | 元教训 |
| 2026-08-08 | docs/REVIEW-ROUND-FLOW-0809.md | 流程 8/08 review |
| 2026-08-09 | v1.3.0(bump + 发布说明) | 分轮演出 + ask 三分类 |
| 2026-08-09 | fix(stage): 多轮修正(比喻正则、行首 markdown、谢幕卡、状态栏注入块时序对齐) | v1.3.0 后热修 |
| 2026-08-09 | Update README.md(描述词微调) | HEAD = f7b06e4 |
8. 复用 / 改造 / 重设计路线¶
仅作研究建议;不作最终决策。鉴于 PolyForm Noncommercial 1.0.0,任何商业复用路径都需作者授权。
| 方向 | 评估 | 主要依据 |
|---|---|---|
| A. 借鉴 RP 专用 harness 模式 | ★★★★ | 分轮演出 + 演段轮回看卡 + ask 接入 + 硬件级门禁 —— 这是梨园独有的工程产出,对所有多轮 LLM 应用都通用(不限于 RP)。 |
| B. 借鉴预设 → 常驻/工具/技能/退场 的内容分流 | ★★★★ | 九性质五去向类型学 + protocol-detect(MVU 退场)是任意 prompt 工程都能复用的元方法。 |
| C. 借鉴 workspace.ts 的「一拍一工作区」模式 | ★★★ | 稿纸 + 写侧执行器 + 自动验收 — 单一职责、强可测性;与 Cindy 的 turnRunner.ts 模型相似,但定位更窄(单拍)。 |
| D. 直接 fork / 二次开发 Liyuan | ★★ | PolyForm Noncommercial 1.0.0 禁止商业用途;个人学习可行;商业化需作者单独授权。 |
| E. 复用 ST 兼容层(卡 / world书 / jsonl) | ★★★ | 独立实现的解析器,无 ST 代码依赖;可作为新 RP 客户端的种子。但导入老卡与新客户端数据兼容需重新协商。 |
| F. 复用 pi 内核 fork 模式 | ★★★ | 冻结 fork + file: 本地依赖 + pi 升级被刻意避免 —— 与 Cindy「通过 pi-host 注入 + 不 fork」风格不同;Liyuan 模式更稳定但失去跟随上游演进的灵活性。 |
| G. 借鉴实测驱动开发文化 | ★★★★ | 23 拍实弹 / 8/03 两拍 / 8/04 8 拍 / 8/05 实弹 —— 实弹数据 + KPI + 验收门禁;每个里程碑都有门禁测试绿数(541/545/452/475/492/564/577)。 |
9. 风险与未尽事项¶
- 许可证风险(最重要):PolyForm Noncommercial 1.0.0 禁止商业用途。任何衍生项目若涉及商业化需作者单独授权。
- NSFW 内容风险:项目含瑟瑟语料(预设 E 类 nsfw 主题)、话痨卡代写 user 对白、内容尺度支持 —— 部署合规需自审。
- 无鉴权 Web 服务:默认 7620 端口裸暴露公网=高风险;必须套反向代理 + 鉴权。
- 冻结 fork 漂移:packages/coding-agent fork 自 pi v0.80.3(2026-06-30),与 Cindy 的 pi-host 注入风格相反 —— pi 上游演进不会自动同步到梨园,bug fix / 性能改进需要手动 cherry-pick。
- 3 个 inspect 超时:均为 pi fork 的 dist/ + 长 test,不阻塞研究,但下游做依赖审计时需特别留意。
- 未覆盖范围:
- web/ 前端 3.3 MB(Vite + React)未深入分析
- docs/superpowers/ 子目录未展开
- assets/lorebooks/ 默认世界书的实际内容未通读(仅识别 MVU 协议条目)
- 实弹数据(
_obs-ma/、_obs-mb/、_obs-mvu/等目录)属于产物级,不在 git 跟踪内 - 性能 / 墙钟 / 思考量 KPI 数字取自作者文档,未独立复测
10. 待确认(按 Profile 规则独立)¶
- 是否晋升稳定版? stable_promotion 需用户单独明确 Approve。
- 是否发布到 Cloudflare Pages
technical-research.pages.dev/research/liyuan/? 涉及 PolyForm Noncommercial 内容引用,需用户确认合规。 - 是否展开横向比较(Cindy vs Liyuan)? 用户此前偏好推迟;如需恢复请告知。
- 是否要进一步深挖:分轮演出引擎 / 预设拆层 / 助手侧双模型 / pi fork 冻结策略?