# Novel Reader

> Intelligent long text novel reader with smart content filtering and detailed asset extraction. Invoke when user wants to read or analyze long novels. Automatically skips irrelevant content and extracts detailed character/item/scene information.

- Skill: `chunpu/novel-reader` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add chunpu/novel-reader`
- Raw SKILL.md: https://api.skillmd.com/api/skills/chunpu/novel-reader/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: chunpu (https://skillmd.com/u/chunpu)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/chunpu/novel-reader

---


# Novel Reader - 智能长文本小说阅读器

使用 Python 安全、可靠地读取长文本小说，解决 LLM 上下文窗口有限的问题。完美支持 UTF-8 编码的中文小说。自动过滤无关内容，实时抽取详细的角色、道具、场景信息。

## 核心功能

- **多格式支持**：如果输入文件是 PDF、DOC、DOCX 格式，先使用 doc-to-txt skill 转换为 TXT 纯文本格式，然后读取转换后的 TXT 文件
- **按字符位置读取**：使用 Python 按字符位置精确读取，不会出现乱码
- **分段读取**：每次读取最多 3000 字符，默认值为 3000 字符，避免超出工具输出限制。**严禁跳读**，必须连续逐段读取
- **灵活定位**：可从任意位置开始读取
- **编码安全**：原生支持 UTF-8 编码，正确处理中文字符
- **智能内容过滤**：通过大模型自动识别并跳过小说中与正文无关的内容（上架感言、作者感谢、访谈、广告等）
- **实时资产抽取**：每读取一段内容，立即识别并记录小说中的角色、道具、场景的详细信息
- **大纲记录**：记录每段内容的摘要，形成完整大纲
- **进度追踪**：记录当前阅读位置、已读字数等进度信息
- **上下文管理**：充分利用 Agent 的上下文 compact 机制，在上下文快用完时自动压缩

## 重要要求

### 严禁跳读
- **必须连续逐段读取**：每次读取 3000 字符后，下一次必须从当前结束位置继续读取（即 start = 上次的 start + 3000）
- **禁止跳读**：绝对不允许跳过中间内容直接跳到后面的位置
- **绝对禁止 for 循环读取**：严禁使用 for 循环批量读取文件（如 `for i in $(seq ...)`），因为 Agent 工具会对输出进行压缩，for 循环会导致内容被截断，当你看到 (some characters truncated) 表示内容已经被截断，你只能手动重新一段一段读取。
- **禁止一个命令多次调用 python 脚本**：每个工具只能输出 3000 字，超出的内容会被截断，一次 tool call 最多只能调用一次 python 命令！
- **提升效率**：因为要读取超长文本，你可以连续调用读取工具脚本（但不能用 for 循环），中间不思考也不说话。
- **更新循环**：每读取 10 个小说片段（每次 3000 字符，共 30000 字符），就更新一次大纲、进度、资产文件，继续下一个循环。
- **禁止预设任务**：禁止使用 TODO 列表，Task 列表相关工具！


## 使用方法

### 核心命令

```bash
python3 read_novel.py <小说文件路径> [--start <起始位置>]
```

### 参数说明

| 参数 | 说明 | 示例 |
|------|------|------|
| `<小说文件路径>` | 小说文件的路径（必填），支持 TXT、PDF、DOC、DOCX 格式。如果是 PDF/DOC/DOCX 格式，先使用 doc-to-txt skill 转换为 TXT | `test-files/novel.txt` 或 `test-files/novel.pdf` |
| `--info` | 获取小说信息（总字符数、总行数、非空行数） | `--info` |
| `--start` | 起始位置（字符索引，从 0 开始，默认：0，可选） | `--start 10000` |

### 示例

获取小说信息：

```bash
python3 read_novel.py ./novel.txt --info
```

读取小说从头开始的 3000 个字符（使用默认参数）：

```bash
python3 read_novel.py ./novel.txt --start 0
```

读取小说从第 3000 个字符开始的 3000 个字符（仅指定 start）：

```bash
python3 read_novel.py ./novel.txt --start 3000
```

查看帮助：

```bash
python3 read_novel.py --help
```

### 工作流

**完整工作流分为三个阶段：文件格式处理 → 初始化 → 循环读取 → 完成总结**

#### 前置步骤：文件格式处理
- 检查输入文件格式
- 如果是 PDF、DOC、DOCX 格式，先使用 doc-to-txt skill 转换为 TXT 纯文本格式
- 转换完成后，使用转换后的 TXT 文件进行后续操作

#### 阶段一：初始化（仅需一次）

**步骤 1：获取小说信息**
```bash
python3 read_novel.py novel.txt --info
```
输出示例：
```
总字符数: 5512508
总行数: 158108
非空行数: 79053
```

**步骤 2：检查读取进度**
- 检查是否存在 `读取进度.txt` 文件
- **如果存在**：读取当前位置，从该位置继续（断点续读）
- **如果不存在**：从位置 0 开始全新读取

#### 阶段二：循环读取（核心阶段）

每个循环读取 10 个片段（共 30000 字符），分为两个子阶段：

**子阶段 A：批量读取（连续执行，中间不分析）**

连续调用 10 次读取命令，每次读取 3000 字符：
- 第 1 次：`--start <当前位置>`
- 第 2 次：`--start <当前位置+3000>`
- ...
- 第 10 次：`--start <当前位置+27000>`

**示例（从 0 开始的第一个循环）：**
```
读取片段 1：--start 0
读取片段 2：--start 3000
...
读取片段 10：--start 27000
```

**示例（从 60000 开始的第三个循环）：**
```
读取片段 21：--start 60000
读取片段 22：--start 63000
...
读取片段 30：--start 87000
```

**⚠️ 关键规则**：10 次读取必须连续执行，中间不分析、不总结、不更新文件

**子阶段 B：分析更新（读完 10 个片段后执行）**

1. 分析这 10 个片段的内容
2. 更新 `大纲.txt`：添加这 10 个片段的章节摘要
3. 更新 `读取进度.txt`：记录当前位置（如 30000）
4. 创建或更新资产文件：提取新出现的角色、道具、场景

**子阶段 C：判断是否继续**
- 计算已读进度（已读字数/总字数）
- 如果未达到用户要求（如"读 5%"）：回到子阶段 A，继续下一批 10 个片段
- 如果已达到用户要求：进入阶段三

#### 阶段三：完成总结

- 输出最终读取进度
- 总结已抽取的资产统计（角色数、道具数、场景数）

#### 执行顺序示例

假设用户要求读取小说前 5%，小说文件是 `novel.pdf`：

**前置步骤：文件格式处理**
- 检查文件格式：.pdf
- 使用 doc-to-txt skill 将 novel.pdf 转换为 novel.txt
- 后续步骤使用 novel.txt 文件

**步骤 1：初始化**
1. 获取小说信息 → 总字数 5512508
2. 检查 `读取进度.txt` → 不存在，从位置 0 开始

**步骤 2：循环读取**

循环 1（片段 1-10，0-30000 字符）：
- 批量读取：连续执行 `--start 0` 到 `--start 27000`
- 分析更新：更新大纲、进度（30000）、资产
- 检查进度：30000/5512508 = 0.54%，未达到 5%，继续

循环 2（片段 11-20，30000-60000 字符）：
- 批量读取：连续执行 `--start 30000` 到 `--start 57000`
- 分析更新：更新大纲、进度（60000）、资产
- 检查进度：60000/5512508 = 1.09%，未达到 5%，继续

循环 3（片段 21-30，60000-90000 字符）：
- 批量读取：连续执行 `--start 60000` 到 `--start 87000`
- 分析更新：更新大纲、进度（90000）、资产
- 检查进度：90000/5512508 = 1.63%，未达到 5%，继续

... 继续循环 ...

循环 10（片段 91-100，270000-300000 字符）：
- 批量读取：连续执行 `--start 270000` 到 `--start 297000`
- 分析更新：更新大纲、进度（300000）、资产
- 检查进度：300000/5512508 = 5.44%，已达到 5%，停止

**步骤 3：完成总结**
- 输出最终进度：5.44%
- 统计资产：角色 X 个，道具 Y 个，场景 Z 个

#### 关键规则

| 规则 | 说明 |
|------|------|
| **严禁边读边分析** | 每读完一个片段就分析更新是错误的做法 |
| **必须批量读取** | 10 个片段全部读完后再统一分析更新 |
| **支持断点续读** | 通过读取进度.txt 实现中断后继续 |
| **进度计算** | 每次循环读取 30000 字符（10 × 3000）|

## 资产抽取

### 智能内容过滤

通过执行 Python 脚本读取小说内容后，让大模型读懂内容，自动识别并忽略与小说正文无关的内容，只保留小说的正文章节内容进行分析和资产抽取。不使用任何规则或正则表达式进行过滤，完全依赖大模型的理解能力。

### 实时资产抽取

每读取一段内容（不超过 3000 字符），立即从中识别并抽取新出现的资产（角色、道具、场景），并实时更新对应的文件。不要等到全部读完再更新。大模型会充分利用上下文 compact 机制，在快用完上下文时自动压缩。

### 抽取元素

从每段读取的内容中，识别并抽取以下三类资产，尽可能收集详细信息：

1. **角色** - 小说中出现的人物，包括：
   - 基本信息：姓名、年龄、性别、身份、角色定位（主角/配角/反派/男二/女二等）
   - 外貌特征：容貌、身高、体型、着装
   - 性格特点：口头禅、习惯性动作、行为模式
   - 背景关系：家庭、朋友、敌人、师承
   - 能力修为：实力等级、特殊能力、武器装备
   - 出场情节：首次出场、重要事件

2. **道具** - 小说中出现的物品、法宝、武器等，包括：
   - 基本信息：名称、类型、来源
   - 外观特征：形状、颜色、材质、大小
   - 功能特性：特殊能力、使用方法、效果
   - 历史背景：来历、前任主人、重要事件
   - 相关角色：拥有者、使用者、争夺者

3. **场景** - 小说中出现的地点、环境、场所等，包括：
   - 基本信息：名称、类型、地理位置
   - 环境特征：地形、气候、建筑风格、氛围
   - 功能用途：居住、修炼、交易、战斗
   - 相关势力：所属势力、管理者、常驻人物
   - 重要事件：发生过的关键情节

### 目录结构

在小说文件所在目录下创建以下结构：

```
小说名或项目名/
├── 大纲.txt
├── 读取进度.txt
├── 角色/
│   ├── <角色名1>.txt
│   ├── <角色名2>.txt
│   └── ...
├── 道具/
│   ├── <道具名1>.txt
│   ├── <道具名2>.txt
│   └── ...
└── 场景/
    ├── <场景名1>.txt
    ├── <场景名2>.txt
    └── ...
```

### 文件内容格式

#### 大纲.txt

```
1. <第一段内容的摘要>

2. <第二段内容的摘要>

...
```

**说明**：
- 按小说内容的逻辑分段添加摘要，不按固定字数分段
- 大模型根据内容自然决定何时添加新的摘要条目
- 每条摘要用序号标识，按阅读顺序排列
- 只记录小说正文内容的摘要，跳过无关内容
- 跳过小说中与正文无关的内容，如上架感言、作者感谢、访谈、广告等

#### 读取进度.txt

```
当前位置: <字符索引>
已读字数: <数字>
总字数: <数字>
进度: <百分比>%
```

#### 角色文件（角色/<角色名>.txt）

每个角色文件包含该角色的详细描述，参考格式如下：

```
<角色名称>

【基本信息】
姓名：
年龄：
性别：
身份：
角色定位：

【外貌特征】
容貌：
身高：
体型：
着装：

【性格特点】
性格：
口头禅：
习惯性动作：
行为模式：

【背景关系】
家庭：
朋友：
敌人：
师承：

【能力修为】
实力等级：
特殊能力：
武器装备：

【出场情节】
首次出场：
```

#### 道具文件（道具/<道具名>.txt）

每个道具文件包含该道具的详细描述，参考格式如下：

```
<道具名称>

【基本信息】
名称：
类型：
来源：

【外观特征】
形状：
颜色：
材质：
大小：

【功能特性】
特殊能力：
使用方法：
效果：

【历史背景】
来历：
重要事件：

【相关角色】
拥有者：
使用者：
争夺者：
```

#### 场景文件（场景/<场景名>.txt）

每个场景文件包含该场景的详细描述，参考格式如下：

```
<场景名称>

【基本信息】
名称：
类型：
地理位置：

【环境特征】
地形：
气候：
建筑风格：
氛围：

【功能用途】
居住：
修炼：
交易：
战斗：

【相关势力】
所属势力：
管理者：
常驻人物：

【重要事件】
发生过的关键情节：
```

### 抽取规则

1. **去重**：如果资产文件已存在，只需追加新的信息，不要重复创建
2. **准确性**：确保抽取的资产名称准确，避免错别字
3. **完整性**：尽可能记录资产的所有相关信息，使用上述详细格式
4. **自然语言**：使用自然语言描述，让大模型理解抽取需求
5. **内容过滤**：在抽取资产前，先过滤掉无关内容，只从正文中抽取
6. **实时更新**：每读取一段内容（不超过 3000 字符），立即识别并抽取新出现的资产，不要等全部读完再更新
7. **不使用规则/正则**：完全通过执行 Python 脚本获取内容，让大模型自己理解和分析，不使用任何规则或正则表达式进行匹配
8. **重要性筛选**：只记录重要的资产，不重要的角色、场景、道具可以忽略跳过。判断标准包括：
   - **角色**：对剧情有推动作用的主要角色、关键配角、重要反派等；路人、龙套、一次性出现的次要角色可忽略
   - **道具**：对剧情有关键作用的法宝、武器、重要物品；普通物品、一次性道具可忽略
   - **场景**：故事发生的主要地点、重要场所；临时场景、一笔带过的地点可忽略

## 技巧提示

1. **获取文件总字符数**：
```bash
python3 -c "
with open('test-files/novel.txt', 'r', encoding='utf-8', errors='replace') as f:
    print(len(f.read()))
"
```

2. **读取分段**：每次读取最多 3000 字符，默认值为 3000 字符，避免超出工具输出限制

3. **上下文管理**：大模型通常有 128k 上下文窗口，Agent 会在快用完上下文时自动压缩，请合理利用

## 为什么用 Python？

- ✅ **编码安全**：原生支持 UTF-8，不会出现乱码
- ✅ **按字符读取**：不是按字节，正确处理中文字符（每个中文字符算 1 个）
- ✅ **跨平台**：Windows/Mac/Linux 都一样
- ✅ **系统预装**：几乎所有现代系统都预装了 Python 3
- ✅ **语法简单**：一个模式搞定所有场景

