Metadata-Version: 2.4
Name: structured-writer-ldxs
Version: 1.1.0b15
Summary: structured-writer — AI Agent
Home-page: https://github.com/Ldxs001/workbuddy-skills
Author: Ldxs (wUwproject)
Author-email: wuwofc@yeah.net
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python
Dynamic: summary

# Structured Writer — 结构化写作智能体

> 模板驱动的大纲规划 + 串行写作引擎。基于 LLM 的结构化长文写作系统，支持两级 RAG 增强、事实自检、引用自动格式化、交互式大纲控制。
>
> 版本：1.1.0b15 | 作者：wUwproject | 许可证：Apache 2.0

---

## 目录

- [一、它是什么](#一它是什么)
- [二、环境要求与依赖](#二环境要求与依赖)
- [三、搭建步骤](#三搭建步骤)
- [四、使用流程总览](#四使用流程总览)
- [五、配置面板详解](#五配置面板详解)
- [六、模板编辑指南](#六模板编辑指南)
- [七、大纲评审详解](#七大纲评审详解)
- [八、关键概念与功能关联](#八关键概念与功能关联)
- [九、写作控制与输出](#九写作控制与输出)
- [十、会话管理](#十会话管理)
- [十一、常见问题](#十一常见问题)
- [协议](#协议)

---

## 一、它是什么

Structured Writer 是一个**本地运行**的结构化长文写作工具。你给它一个主题，它会：

1. 按你选定的**模板**（公文、学术论文、综述、新闻、报告等）规划出结构化大纲
2. 让你在浏览器里**交互式调整**大纲（勾选、排序、改字数、标记重点、绑定知识库）
3. 逐节**串行写作**，每节写作时自动注入前文回顾、RAG 参考资料、辅助知识
4. 输出完整的 Markdown 文章，支持事实自检标注与参考文献自动格式化

核心设计理念：**模板决定结构，大纲承载规划，写作引擎只负责执行**。

---

## 二、环境要求与依赖

| 依赖 | 说明 | 获取方式 |
|------|------|---------|
| **Python** | 3.10 及以上 | python.org |
| **LLM 推理服务** | LM Studio 或 Ollama，二选一，本机运行 | LM Studio / Ollama 官网 |
| **RAG 智能体**（可选但强烈推荐） | rag-assistant **v2.2.10 及以上**，提供知识库检索能力 | 见下方两种安装方式 |

### 获取 RAG 智能体

| 渠道 | 名称 | 说明 |
|------|------|------|
| **PyPI** | `rag-assistant-ldxs` | `pip install rag-assistant-ldxs`，安装后运行 `python main.py --no-web --api-port 8767` |
| **GitHub** | `Ldxs001/workbuddy-skills` 仓库 → `agent/rag-assistant` 目录 | 下载后运行 `python main.py --no-web --api-port 8767` |
| **Gitee** | `wUwproject/workbuddy-skills` 仓库 → `agent/rag-assistant` 目录 | 同上（国内访问更快） |

> **版本要求**：必须 **2.2.10 及以上**。Structured Writer 依赖 rag-assistant 的 `/api/kb/query` 外部接口（端口 8767），低版本缺少文档元数据回填能力，引用功能无法工作。
>
> **端口说明**：rag-assistant 的**外部 API 端口是 8767**（注意不是它的 Web 界面 8765）。Structured Writer 只通过 8767 与它通信。

---

## 三、搭建步骤

### 方式一：Windows 一键启动

```
1. 确保 LM Studio（或 Ollama）已运行，且已加载一个模型
2. 双击 setup.bat
3. 浏览器访问 http://localhost:8770
```

### 方式二：手动启动

```bash
# 1. 安装依赖
pip install -r requirements.txt

# 2.（推荐）先启动 RAG 智能体的外部 API
python rag-assistant路径/main.py --no-web --api-port 8767

# 3. 启动 Structured Writer
python main.py

# 4. 浏览器访问 http://localhost:8770
```

### 搭建后的首次配置

| 步骤 | 操作 |
|------|------|
| 1 | 打开**配置**面板，在「规划模型」和「写作模型」区填入你的 LLM 服务地址，点「刷新」加载模型列表并选择 |
| 2 | （可选）在配置面板填入 rag-assistant 的路径，点「冷启动 RAG」——工具会自动拉起 rag-assistant 子进程 |
| 3 | 选择一个模板，开始写作 |

> **端口**：Structured Writer 默认 8770。可用 `python main.py --port 9000` 修改。

---

## 四、使用流程总览

```
选择模板 → 填写元数据 → 发送主题
    ↓
[规划] LLM 按模板生成结构化大纲
    ↓
[评审] 调整大纲：勾选/排序/字数/重点/RAG/辅助知识
    ↓
[生成] 逐节串行写作（自动注入 RAG、前文回顾、事实自检）
    ↓
[输出] Markdown 文章 + 会话保存
```

**一句话流程**：模板定骨架 → LLM 填血肉 → 你掌舵 → 引擎执行。

---

## 五、配置面板详解

配置面板分为以下几个区域：

### 1. 模型配置

| 配置项 | 说明 |
|--------|------|
| **规划模型** | 负责生成大纲。建议与写作模型同级或同模型。**推理类模型建议 max_tokens 不低于 2048**，低于此值推理会吃光 token 导致无法输出 |
| **写作模型** | 负责逐节写作。建议上下文窗口大一些（长文写作需要） |
| **温度** | 规划默认 0.6、写作默认 0.7。越低越稳定，越高越有创意 |
| **超时** | 规划 180 秒、写作 300 秒。推理模型思考时间长，不建议调太小 |

### 2. 模板管理

| 操作 | 说明 |
|------|------|
| **切换模板** | 下拉选择，内置 8 套：日常写作 / 学术论文 / 正式公文 / 新闻报道 / 技术报告 / 通用公文 / 论文综述 / 自定义 |
| **编辑模板** | 直接修改表格字段（见「模板编辑指南」） |
| **另存为** | 基于当前模板创建副本 |
| **删除** | 仅自定义模板可删（内置模板只读） |
| **从对话生成模板** | 用一句话描述文档需求，LLM 自动生成完整模板——不需要手工搭结构 |

### 3. RAG 配置

| 配置项 | 说明 |
|--------|------|
| **RAG 路径** | rag-assistant 的安装路径，用于「冷启动 RAG」自动拉起子进程 |
| **冷启动 RAG** | 一键启动 rag-assistant 并等待外部 API（8767）就绪 |
| **停止 RAG** | 关闭 rag-assistant 子进程 |

> **RAG 状态灯**：配置页会实时显示 8767 是否在线。只有在线时，大纲里的 RAG 复选框才可用。

### 4. 写作参数

| 配置项 | 默认 | 说明 |
|--------|------|------|
| **前文回顾字数** | 8000 | 每节写作时注入的"已写内容回顾"上限。文章很长时建议调小，防止上下文超限 |
| **事实自检** | 关 | 开启后写作模型在每节末尾自动标记不确定的事实，文章末尾汇总成「建议人工复审」清单，**零额外 LLM 调用** |
| **会话上限** | 20 | 活跃会话超过此数时自动归档最旧的 |

---

## 六、模板编辑指南

模板由四部分组成，各自独立、互不干扰：

| 部分 | 作用 | 说明 |
|------|------|------|
| **meta（元数据区）** | 文章的短标识信息 | 标题、作者、单位、文号等 |
| **content（内容树区）** | 文章的正文骨架 | 引言、方法、结论、参考文献等 |
| **style（风格提示词）** | 全文统一文风 | 注入每一步写作，如"学术严谨风格，引用规范" |
| **logic（逻辑提示词）** | 写作认知顺序 | 控制先写什么后写什么，**不影响文章最终排列** |

### 元数据字段（meta）

| 字段 | 说明 |
|------|------|
| **source=user** | 用户必须填，LLM 不碰（作者、单位、文号） |
| **source=auto** | 用户可填，留空则由 LLM 生成（标题） |
| **source=llm** | 必须由 LLM 生成 |
| **显示标签** | ☑ 渲染时显示"名称：值"；☐ 不显示标签，有值才渲染 |

### 内容树字段（content）

| 字段 | 说明 |
|------|------|
| **type=leaf（叶子节）** | 无子结构，单段直接写。适合：关键词、摘要、参考文献 |
| **type=section（章节节）** | 自动拆分为 2-4 个子结构。适合：引言、方法、讨论 |
| **字段意义（desc）** | **本节的权威写作要求**，会确定性注入该节写作提示（见「字数为 0」与「本节要求」） |
| **重点节（is_key）** | 标记后该节字数可上浮 50% |
| **逻辑顺序（logical_order）** | 控制写作顺序，如"摘要、参考文献最后写" |
| **引用校验（在配置界面勾选「引用」）** | 勾选后该节跳过 LLM 写作，由系统自动生成参考文献，见「参考文献自动格式化」 |

---

## 七、大纲评审详解

规划完成后进入大纲评审界面，你可以对每一节做以下调整：

| 操作 | 方式 | 效果 |
|------|------|------|
| **勾选/取消** | 复选框 | 取消的节/子结构**完全跳过**：不写标题、不占字数、不参与进度统计 |
| **排序** | 节 1-N、子结构 i-iv 下拉 | 调整**最终文章**的排列顺序 |
| **字数** | 输入框 | 覆盖该节/子结构的字数要求 |
| **重点** | ⭐ 复选框 | 该节字数可上浮 50% |
| **RAG** | 勾选 + 选择知识库 | 该节写作时自动检索知识库注入参考（需 8767 在线） |
| **辅助知识** | 子结构旁「+」按钮 | 为该子结构附加文本/文件，写作时**优先采用** |
| **重新规划** | 按钮 + 模态框 | 输入调整要求（如"增加两节、引言写短些"），LLM 按新要求重生成大纲 |

> **辅助知识与 RAG 的区别**：RAG 是知识库自动检索（系统决定查什么），辅助知识是你明确指定要写进去的内容（你决定用什么）。两者独立注入，互不覆盖。

---

## 八、关键概念与功能关联

### 1. 字数为 0 的含义

| 场景 | 含义 |
|------|------|
| **你在评审界面把字数设为 0** | 不做字数限制，该节自由发挥 |
| **leaf 节模板未写字数** | 自动为 0 = 不限字数，**由该节的字段描述（desc）约束输出形式**。例如"关键词"节的描述是"仅输出3-5个关键词，不要段落"，字数 0 + 描述 = 输出列表而非长文 |
| **引用节（在配置界面勾选「引用」）** | 在**模板编辑界面**给该节勾选「引用」后，规划大纲时该节字数**自动设为 0**，写作时**完全跳过 LLM**，由系统自动生成参考文献列表 |

> **重点**：字数只是约束之一，**真正决定一节"写成什么样"的是模板里的字段描述**。描述怎么写，LLM 就怎么写。

### 2. 两级 RAG 检索

开启 RAG 的节，写作时会做**两次**检索：

```
节级检索：以"文章主题 + 节标题 + 节要点"为查询 → 注入【背景资料】
子结构级检索：以"节标题 + 子结构标题"为查询 → 注入【针对性资料】
```

两次结果都注入该子结构的写作提示，LLM 选择性参考。

### 3. 参考文献自动格式化（学术/综述模板）

在**模板编辑界面**给某一节（必须为 leaf 类型）勾选「引用」并指定格式（如 `[x]=1.`）后，全流程自动：

```
规划时：该节字数自动设为 0，标记为引用节
写作时：正文中出现"引用自来源N" → 自动替换为用户配置的格式（如 [1]）
      该引用节本身跳过 LLM 写作
生成后：根据 RAG 检索到的文档元信息自动构建参考文献列表
        → 按模板要求的格式（如 GB/T 7714）由 LLM 规范化
        → 直接替换进参考文献节
```

**关联性要求**：引用功能需要同时满足
1. 在模板编辑界面给该节（leaf 类型）勾选了「引用」并指定格式
2. 该文启用了 RAG 且检索到了带元信息的文档
3. rag-assistant ≥ 2.2.10（提供文档元数据）

### 4. 前文回顾与续写

- **前文回顾**：每节写作时注入前面已写内容（按配置字数截断），保证逻辑连贯。长文建议调小回顾字数防超限
- **续写机制**：写作模型输出被 token 上限截断时，自动追加"请继续写"指令接着写，直到完成或内容为空

### 5. 事实自检

开启后，写作模型在每节末尾用**内嵌标记**标注自己不确定的数据/前沿信息/案例（不额外调用 LLM）。文章末尾自动生成「建议人工复审」清单——即使全部无问题也会输出"未发现需标记的问题"。

### 6. 逻辑顺序 vs 输出顺序

模板的 `logic`（逻辑提示词）和 content 的 `logical_order` 控制**写作顺序**，大纲评审的排序控制**输出顺序**。两者独立——例如学术论文：引言→方法→结论先写，摘要、参考文献最后写（写作顺序），但最终文章里摘要仍在开头、参考文献仍在结尾（输出顺序）。

---

## 九、写作控制与输出

### 写作过程中的控制

| 控制 | 说明 |
|------|------|
| **自动撰写** | 单篇：输入主题一键完成规划+生成；批量：多行主题逐篇自动撰写，实时进度 |
| **延时停止** | 当前子结构写完后停止，已写内容保留 |
| **立即停止** | 在续写边界停止 |

### 输出

- 每篇文章输出为 Markdown 文件，保存在 `data/outputs/`
- 完成后可在界面查看内容、读取、删除
- 文章包含：标题 + 元数据块 + 各节正文 + （可选）事实自检清单 + （可选）参考文献列表

---

## 十、会话管理

| 操作 | 说明 |
|------|------|
| **新建会话** | 每次规划自动创建 |
| **加载会话** | 断线重连或返回历史，恢复大纲与进度 |
| **归档** | 移入归档区（不删除），侧栏整洁 |
| **恢复** | 归档会话移回活跃区 |
| **删除** | 永久删除（有确认） |
| **自动限额** | 活跃会话超过上限（默认 20）自动归档最旧的 |

---

## 十一、常见问题

**Q：为什么关键词/摘要节输出了一大段正文而不是列表？**
A：请确认使用的是 v1.1.0b15 及以上版本。旧版本存在"模板字段描述未注入写作提示"的问题。新版本中，leaf 节的字数按模板描述解析（关键词这类无字数描述的自动为 0），且模板字段描述会作为「本节要求」确定性注入写作提示。

**Q：RAG 复选框灰色不可用？**
A：说明 rag-assistant 的外部 API（8767）不在线。在配置面板点「冷启动 RAG」或手动启动，等状态灯变绿。

**Q：写作中途报错 / 某节内容为空？**
A：常见原因是写作模型被 token 截断后输出为空（推理模型思考吃光 token）。建议：提高写作模型的 max_tokens、换上下文窗口更大的模型、或把前文回顾字数调小。

**Q：参考文献没有自动生成？**
A：检查三点：① 模板编辑界面是否给该节（leaf 类型）勾选了「引用」；② rag-assistant 是否 ≥ 2.2.10 且在线；③ 该文是否启用了 RAG 并检索到文档。

**Q：如何在公网访问？**
A：默认监听 0.0.0.0:8770，局域网可直接访问。公网访问建议配合反向代理，注意配置中不要存放敏感信息。

---

## 协议

Apache 2.0 © wUwproject


---

## 更新说明

## [1.1.0b15] - 2026-07-31
### 修复
- **关键词节输出一整套写作（desc 指令丢失）**：模板 content 项的 desc（如"仅输出3-5个关键词，不要段落"）在规划→写作之间丢失——写作引擎只注入大纲的 word_count + summary，从不读模板 desc；而规划器给关键词这类 leaf 节兜底 800 字，写作提示变成"约800字"诱导长文。修复两处：
  1. **desc 确定性注入【当前章节要求】**：写作时按节名匹配模板 content，将 desc 作为"本节要求"注入写作提示，不依赖规划器转述
  2. **leaf 字数按 desc 解析、拒绝 800 兜底**：新增字数解析函数，leaf 节 desc 无数字→0（字数不限，由 desc 指令约束）、有数字（如"200-300字"）→取中值；section 节保持现状（desc 无数字→800 或保留规划器值）
### 变更
- `planner.py` 提取 `_parse_word_count`，规范化补全与已存在节共用同一字数解析逻辑（leaf 强制按 desc，section 不动）
- `writer.py` 写作提示新增"本节要求"区块（模板 desc），与"写作要点"（规划器 summary）分离，互不污染
