# Fastdeai

> Markdown 去'AI 味儿'清洗工具(fastdeai.exe · self-contained 单文件,.NET 9,目标机免装运行时)。何时调用——★首要触发:拿到一份 AI 生成的 Markdown,想去掉那些'人类不会写'的格式装饰(装饰 emoji、引用框 >、分隔线 ---、斜体 *x*、删除线 ~~x~~、行内代码 `x`、加粗 **x**、图片、HTML 标签、脚注),只留纯文本结构(标题/表格/列表/段落),强调由作者后续手动重施加时 → 优先本 skill。①清洗 AI 生成的文档/报告/笔记;②批量给一个目录下的 .md 统一去味儿;③粘贴进来的大模型输出太花、要变成干净底稿。核心心法:代码围栏块是绝对原文保护区(里面的 **、`、>、emoji 一律不动)+ 正文行紧跟 --- 会被当 setext 标题而非删除分隔线(易误判)+ snake_case 的下划线保留。含完整清洗规则(保护/保留/转换/删除)、已验证语义坑、bash 调用约定、批量 recipe、与 fastsearch/Read 分工。载体为 self-contained exe(依赖 System.Text.Rune,无法内嵌进 PS5.1),源码在源码树。

- Skill: `elabalice-code/fastdeai` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add elabalice-code/fastdeai`
- Raw SKILL.md: https://api.skillmd.com/api/skills/elabalice-code/fastdeai/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: elabalice-code (https://skillmd.com/u/elabalice-code)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/elabalice-code/fastdeai

---


# fastdeai — Markdown 去「AI 味儿」

> 跨项目 Markdown 清洗工具。去掉 AI 生成时爱追加、但人类不会写的格式装饰(装饰 emoji、引用框、分隔线、斜体 / 删除线、行内代码、加粗、图片、HTML、脚注),只保留有信息量的纯文本结构(标题、表格、列表、段落)。强调(加粗 / 斜体)由作者后续手动重新施加。
> 实战提炼,持续维护。

> **载体**:`~/.claude/skills/fastdeai/fastdeai.exe` —— self-contained 单文件(.NET 9,所有 DLL 折叠进 exe,**目标机无需安装 .NET 运行时**)。**为何用 exe 而非像 fastsearch 那样内嵌 C#**:fastdeai 重度依赖 `System.Text.Rune`(.NET Core 3.0+ 才有,**PS5.1 的 .NET Framework 没有该类型**)且用了 C#8/9 语法,无法内嵌进 PS5.1 的 CodeDom/C#5 即时编译。故以 exe 为权威载体,语义 100% 由源码决定。另有 `fastdeai.ps1` 薄包装提供 exe 缺的**批量目录**能力,单文件透传语义不变。

## 何时用

- **★ 清洗 AI 生成的 Markdown(首要触发)**:文档里满是装饰 emoji、`>` 引用框、`---` 分隔线、`**加粗**`、`` `行内代码` ``、`~~删除线~~`、`![](图片)`、HTML 标签等"AI 味儿",想要干净纯文本底稿时 → **优先本 skill**(比手写正则/逐个 Edit 可靠全面得多)。
- **批量去味儿**:一个目录下几十份 AI 生成的 `.md`,统一清洗成底稿。
- **大模型输出落地**:粘进来的 ChatGPT/Claude 输出太花,先去味儿再人工精修/重排版。
- **强调由作者重施加**:工具**故意**把加粗/斜体一起去掉(见维护笔记),让你按自己的强调意图重新标。

> 不适用:只需要读/改特定行 → 用 Read/Edit;只需要在某文件里定位内容 → 用 fastsearch/Grep;要保留全部 Markdown 格式 → 别用本工具(它会剥格式)。

## 0. 心法(一句话)

**代码围栏块是绝对原文保护区 → 正文行紧跟 `---` 会被当 setext 标题(不是删分隔线)→ 去味儿后强调自己重新加。**

## 1. 前置:定位入口 + 调用约定

入口是 skill 自带的 self-contained exe(优先,固定位置);另有 ps1 薄包装提供批量能力。

```bash
# exe 直接可调(无需 powershell -File 前缀,不像 fastsearch 的 ps1 载体)
ls "$HOME/.claude/skills/fastdeai/fastdeai.exe"
```

**bash 调用约定**:

```bash
# 方式一(推荐):定义一次 bash 函数,后续像命令一样用
fastdeai() { "$HOME/.claude/skills/fastdeai/fastdeai.exe" "$@"; }
fastdeai report.md                       # → 生成 report_out.md
fastdeai report.md cleaned.md            # → 指定输出名

# 方式二:批量(需经 ps1 包装;exe 本身不支批量)
powershell.exe -NoProfile -ExecutionPolicy Bypass \
  -File "$HOME/.claude/skills/fastdeai/fastdeai.ps1" -Batch "D:\docs" -Recurse
```

> 下文示例一律用 `fastdeai ...` 简写(假定已按方式一定义函数;或自行脑补 exe 全路径)。
> 无参数运行 `fastdeai` 可显示官方 usage(权威,以它为准)。

## 2. 完整用法

```
fastdeai.exe <input.md> [output.md]      # 单文件,输出可选
fastdeai.ps1 -Batch <dir> [-Recurse]     # 批量(ps1 包装,exe 不支持)
```

| 参数 / 选项 | 作用 |
|---|---|
| `<input.md>` | 输入 Markdown 文件(必填) |
| `[output.md]` | 输出路径(可选)。缺省 → 输入文件旁的 `<原名>_out.md` |
| `-h --help /?` | 显示 usage |
| `-Batch <dir>` | (ps1 包装)批量处理目录下所有 `*.md`,自动跳过已生成的 `*_out.md` |
| `-Recurse` | (ps1 包装)递归子目录 |

**退出码**:`0`=成功 · `1`=异常 · `2`=参数错误(如输入不存在、输入==输出路径) · `3`=ps1 包装找不到 exe / 批量目录不存在。**无参运行**=显示 usage 并返回 `0`。

**输出编码**:统一 UTF-8 **无 BOM**、`\n` 换行(实测确认),中文安全。

## 3. 清洗规则(权威,源自源码)

> 关键原则:**代码围栏块是"原文保护区"**——以下所有转换/删除只在围栏外生效,围栏内任何符号(`**`、`` ` ``、`>`、emoji、`---`)都保持原样。

**原样保护(不动):**
- YAML front matter(首行 `---` … 闭合 `---`)
- 代码围栏块(` ``` ` 或 ` ~~~ `,≥3 个)及其内部全部内容

**保留结构(内容仍走 inline 清洗):**
- 标题(ATX `#`、setext,见 §4.2)、表格(GFM)、列表(有序/无序/任务列表 `- [x]`)、段落文本

**转换(去格式,留内容):**
- 加粗 `**x**` / `__x__` / `***x***` → 去标记,留文字
- 行内代码 `` `code` `` → 去反引号,留内容
- 斜体 `*x*`、删除线 `~~x~~` → 去标记,留文字
- 链接 `[文字](url)` / `[文字][ref]` → 纯文字
- 引用块 `>` → 去标记,留正文

**删除:**
- 图片 `![alt](url)`
- 分隔线 `---` / `***` / `___`(≥3,孤立时)
- 装饰 emoji(🎯📌✅💡🚀🔥⭐✨📊📈🔍📝⚠❗❓🔔🆕👍 等 ~45 种 + variation selector)
- HTML 标签 / 块 / 注释(`<div>`、`<details>`、`<!-- -->` 等)
- 脚注定义 `[^x]:` 与引用 `[^x]`

## 4. ⚠️ 已验证语义坑(清洗前必读)

> 实测沉淀,绕过这些会误判结果。下列行为逐条经样本验证。

1. **代码围栏块绝对保护**:围栏内的 `**bold**`、`` `code` ``、`> quote`、`🎯 emoji`、`---` **全部原样保留**,清洗规则不生效。不确定某符号为何没被去掉时,先看它是否在代码块里。
2. **Setext heading 自动转 ATX(README 未提,易误判)**:「正文行」紧跟 `===` → `# 正文`;紧跟 `---` → `## 正文`。**坑**:文档里一段正文下面跟了一条 `---` 当分隔线,但前面紧挨着非空正文行 → 它会把那行**升成 `##` 标题**(而非删除分隔线)!只有 `---` 前面是空行/标题/表格行(不可提升)时,才当分隔线删除。想确保 `---` 被删,前面留一个空行。
3. **snake_case 保留**:字母数字之间的 `_` 不当斜体(`snake_case_var`、`a_file.txt` 原样)。CommonMark 语义:开闭 `_` 两侧不能是字母数字。
4. **删除后残留空格**:删 emoji/图片/分隔线后,原位置可能残留少量空格(如「文字 🚀 后续」→「文字  后续」)。已知限制,作者后续手动收。
5. **多空行折叠为单空行**;首尾空白行裁剪。输出结构干净。
6. **行内代码反引号未闭合**→ 当字面量保留;**强调标记跨行未闭合**(如 `**粗\n体**`)→ 按字面量处理,不强转。
7. **4 空格缩进代码块不受保护**:按普通文本处理(避免误伤列表续行)。要保护代码,用 ` ``` ` 围栏。
8. **输入==输出路径会报错退出**(码 2),防覆盖源文件。

## 5. recipe 库(实战沉淀)

```bash
# 定义入口函数(每会话一次,或写进 ~/.bashrc)
fastdeai() { "$HOME/.claude/skills/fastdeai/fastdeai.exe" "$@"; }

# —— 单文件清洗 ——
fastdeai report.md                       # → report_out.md(同目录)
fastdeai report.md cleaned.md            # → 指定输出名

# —— 批量目录(ps1 包装;exe 本身不支批量)——
powershell.exe -NoProfile -ExecutionPolicy Bypass \
  -File "$HOME/.claude/skills/fastdeai/fastdeai.ps1" -Batch "D:\notes" -Recurse
# 自动跳过 *_out.md,末尾打印 Cleaned / Skipped / Failed 计数

# —— 先看会清成什么样,再决定要不要批量(无损:输出到独立文件)——
fastdeai sample.md _preview.md && cat _preview.md
```

**清洗前后对照(实测样本节选)**:

```markdown
# 🎯 Title with emoji            →   # Title with emoji
> This is a **blockquote**       →   This is a blockquote
**bold** *italic* ~~strike~~     →   bold italic strike
snake_case_var a_file.txt        →   snake_case_var a_file.txt(下划线保留)
![alt](url) image dropped.       →   image dropped.(图片删,残留空格)
---                              →   (分隔线删除,或上文升为 setext 标题,见 §4.2)
- [x] done **bold** task         →   - [x] done bold task
| **a** | `b` |                  →   | a | b |(表格留,单元格内清洗)
```csharp                         →   ```csharp(整个块原样,内部 ** ` > 🎯 不动)
var x = "🎯 stays";              →   var x = "🎯 stays";
```                              →   ```
Setext Heading                   →   # Setext Heading(=== 升为 #,见 §4.2)
```

## 6. 与其它工具分工

| 场景 | 工具 |
|---|---|
| 去 Markdown 的 AI 味儿格式(emoji/加粗/引用/分隔线…) | **fastdeai**(本 skill) |
| 大海捞针 + 与或非定位文件/日志 | fastsearch |
| 读干净内容 / 单关键词计数 / `-o` 提取 | Grep(ripgrep) |
| 读特定行/整个文件 | Read |
| 改特定片段 | Edit |

> 典型流水线:**fastsearch 布尔定位含 AI 味儿的 `.md` → fastdeai 批量清洗成底稿 → 作者手动重施加强调/精修**。

## 7. 维护笔记(给维护者)

> **🔐 授权**:用户(ElabAlice)授权——agent 可按需直接维护本 skill(SKILL.md / fastdeai.ps1);**改清洗语义需改 C# 源码并重新 `dotnet publish` 出 exe**(见下流程)。

- **载体决策**:fastsearch 把 C# 内嵌进 ps1 让 PS5.1 跑;fastdeai **做不到**——`System.Text.Rune`(.NET Core 3.0+)在 PS5.1 的 .NET Framework 里不存在,且源码用 C#8(`^1` 索引/`..` 范围)/C#9(target-typed `new()`)语法,PS5.1 CodeDom 只支持 C#5。故以 **self-contained exe 为权威载体**(目标机免装 .NET),ps1 仅做透传 + 批量。
- **源码 source of truth**:`0_FastTool/17_FastDeai/workspace/fastdeai_src/fastdeai/{Program.cs, MarkdownCleaner.cs}` + `fastdeai.csproj`。emoji 白名单见 `MarkdownCleaner.cs` 的 `DecorativeEmoji`(`HashSet<Rune>`,~45 个 + `0xFE0F` variation selector)。
- **改 C# → 更新 exe 流程**:改源码 → `0_FastTool/17_FastDeai/workspace/fastdeai_src/build_release.ps1`(dotnet publish 单文件 self-contained)→ 把生成的 `fastdeai_release/fastdeai.exe` 复制覆盖 `~/.claude/skills/fastdeai/fastdeai.exe`。ps1 包装无需动(语义全在 exe)。
- **ps1 包装边界**:`fastdeai.ps1` 仅透传单文件参数 + `-Batch` 批量(自动跳过 `*_out.md`),不碰清洗逻辑;PS5.1 兼容语法。批量输出固定为各自旁边的 `<原名>_out.md`(由 exe 决定,包装不覆盖)。
- **emoji 白名单扩展**:要新增删的 emoji,在源码 `DecorativeEmoji` 加对应 `new Rune(0xXXXX)`,重新 publish。注意 emoji + variation selector(0xFE0F)/ZWJ(0x200D)的粘连处理已在 `CleanInlineNonCode` 里。

