---
name: material-ingest
description: 拆解文章，提取可复用的素材（观点、数据、案例、金句、类比、方法论），分类标注后存入素材库。当用户说"拆解素材""入库""收集这篇文章""提取素材""分析这篇文章的要点"或投喂文章希望留存有价值内容时使用此技能。即使用户只是分享文章并表达"这篇不错"，也应考虑是否需要入库。
license: MIT
metadata:
  author: simonwong
  version: "1.2.0"
---

# 素材拆解入库

从文章中提取可独立复用的素材，分类标注后存入素材库。

## 核心理念

好的写作需要素材积累。这个技能把"读到一篇好文章"变成"素材库里多了几条可以用的东西"。

拆解的关键原则：**以"能独立引用"为粒度标准**。一条素材脱离原文上下文后，读者依然能理解它在说什么。如果一段话必须配合前后文才看得懂，那它不适合作为独立素材。

## 数据目录

所有素材存放在 `./writing-workspace/materials/`：

```
writing-workspace/materials/
├── index.jsonl       # 素材索引（JSONL 格式，每行一条 {id, summary, tags, type, source_title}）
└── entries/          # 每条素材一个 JSON 文件
    └── mat_xxx.json
```

首次使用时自动创建目录结构。

## 模式判断

根据用户措辞判断来源类型：

- 用户说"这是我写的""拆一下我的文章""分析下我这篇" → **自写模式**（`is_self: true`）
- 其他情况 → **外部来源模式**（`is_self: false`）

两种模式的基本拆解逻辑相同，自写模式有额外步骤。

---

## 拆解逻辑

### 第一步：通读理解

先通读全文，理解：
- 文章的核心主题是什么
- 作者的论证结构（先说什么后说什么，为什么这么安排）
- 哪些是作者的原创观点，哪些是引用的

### 第二步：按语义单元拆解

不按段落机械切割，而是按"观点/论据"语义单元拆解：

| 遇到这种内容 | 拆解为 |
|-------------|--------|
| 一个完整的观点或论断 | 一条 `viewpoint` 素材 |
| 支撑观点的数据/统计 | 一条 `data` 素材 |
| 具体案例或故事 | 一条 `case` 素材 |
| 值得直接引用的精彩句子 | 一条 `quote` 素材 |
| 生动的类比或比喻 | 一条 `analogy` 素材 |
| 可操作的方法论或框架 | 一条 `method` 素材 |

一篇文章通常拆出 3-10 条素材。太少说明文章信息密度低或拆解不够细，太多说明粒度太细了。

### 第三步：标注元信息

为每条素材标注：

- **tags**：2-5 个标签。标注前先读取现有 `index.jsonl`，参考已有标签避免同义重复（比如已有"创业"就不要再用"初创"）。如果素材库为空，自由标注。
- **sentiment**：`positive`（正面肯定）/ `negative`（批判否定）/ `neutral`（中性陈述）/ `provocative`（挑衅引发思考）
- **reusability**：`high`（几乎可以直接用）/ `medium`（需要适配语境）/ `low`（参考价值为主）

### 第四步（自写模式额外步骤）

如果是用户自己写的文章，额外做：

1. **标记精彩表达**：找出写得特别好的句子或段落，type 标记为 `my_expression`。这些是用户自己的语言积累，日后创作时优先复用。
2. **标记可深挖观点**：找出有潜力但没展开的论点，增加 `"potential": "expandable"` 字段。这些是未来选题的种子。
3. **关联现有素材**：如果素材库已有内容，指出这篇文章用到了哪些已有素材的观点，以及还有哪些相关素材没用上。

---

## 执行流程

1. 确保 `./writing-workspace/materials/` 目录存在，不存在则创建（含 `entries/` 子目录）
2. 如果 `index.jsonl` 不存在，创建空文件
3. **读取现有数据（必须完成，不可跳过）**：
   - Read `index.jsonl`，逐行解析，了解已有标签和素材（用于去重和标签一致性）
   - 记住最后一行的 ID，后续用于编号
   - 如果 `index.jsonl` 为空或不存在，用 `ls` 列出 `entries/` 目录确认是否真的没有已有数据
4. 通读全文，理解主题和结构
5. 按语义单元拆解，每个单元生成一条素材
6. 为每条素材标注类型、标签、情绪、可复用程度
7. 如果是自写模式，执行额外步骤
8. 素材 ID 格式：`mat_YYYYMMDD_NNN`。**NNN 确定方式：取 `index.jsonl` 最后一行的 ID 序号，再列出 `entries/` 目录下当日已有的 `mat_YYYYMMDD_*.json` 文件，以两者中较大的序号 +1 作为起始编号。** 如果索引为空且当日无已有文件，才从 001 开始。绝不盲目从 001 开始。
9. 将每条素材写入 `materials/entries/{id}.json`
10. **立即更新 `materials/index.jsonl`**——先 Read 当前文件的完整内容，然后在末尾追加新条目。**禁止用 Create/Write 工具从零重写整个文件；必须保留已有内容，只追加新行。** 每条一行 JSON `{id, summary, tags, type, source_title, reusability}`。索引是检索的入口，这一步不能跳过。
11. 向用户展示入库报告

## 素材条目 JSON 结构

```json
{
  "id": "mat_20260327_001",
  "source": {
    "title": "原文标题",
    "author": "作者",
    "url": "来源链接（如有）",
    "date": "发布日期（如有）",
    "is_self": false
  },
  "content": "提取的核心内容原文（保留原始措辞）",
  "summary": "一句话摘要（15-30字）",
  "type": "viewpoint",
  "tags": ["AI", "创业"],
  "sentiment": "positive",
  "reusability": "high",
  "potential": null,
  "created_at": "ISO 8601 时间戳"
}
```

自写模式下 `type` 可以是 `my_expression`，`potential` 可以是 `"expandable"`。

## 索引条目结构

`index.jsonl` 中每行一条记录，只保留摘要信息，用于快速检索：

```jsonl
{"id":"mat_20260327_001","summary":"一句话摘要","tags":["AI","创业"],"type":"viewpoint","source_title":"原文标题","reusability":"high"}
{"id":"mat_20260327_002","summary":"另一条摘要","tags":["产品"],"type":"case","source_title":"原文标题","reusability":"medium"}
```

## 输出格式

入库完成后，向用户展示入库报告：

```
## 素材入库报告

**来源：** 《文章标题》 by 作者
**提取素材：** 6 条

| # | 类型 | 摘要 | 标签 | 复用度 |
|---|------|------|------|--------|
| 1 | viewpoint | AI Agent 的核心价值在于... | AI, 认知 | high |
| 2 | case | Anthropic 的 Claude 从对话工具到... | AI, 产品 | medium |
| 3 | quote | "最好的工具是让你忘记工具本身的存在" | 产品, 设计 | high |
| ... | | | | |

素材已保存到 writing-workspace/materials/entries/
```

自写模式额外展示：

```
### 精彩表达（值得沉淀）
- mat_20260327_004 [my_expression]: "技术债不是欠别人的钱，是欠未来的自己一个交代"

### 可深挖观点
- mat_20260327_002 [expandable]: 关于 AI 产品化的观点还可以继续展开，素材库里有这些相关素材可参考：
  - mat_20260320_003: ...
  - mat_20260315_007: ...
```

## 注意事项

- `content` 字段保留原文措辞，不要改写。素材的价值在于保留原始表达，改写是创作技能的工作。
- **写入 JSON 时必须正确转义特殊字符**：`content` 和其他文本字段中的双引号 `"` 必须转义为 `\"`，反斜杠 `\` 转义为 `\\`，换行符转义为 `\n`。使用 Write 工具写入 JSON 时，确保字符串值中不包含未转义的双引号。
- 如果文章过短（<200 字）或信息密度很低，直接告诉用户"这篇文章信息量较少，建议整篇保留作为参考而非拆解素材"。
- 每条素材的 `summary` 要能独立理解，不依赖原文上下文。
