原力注入

从文本到语义:让智能体高效处理 Markdown 的结构化语义中间层

从文本到语义:让智能体高效处理 Markdown 的结构化语义中间层

一、引言:智能体编辑 Markdown 的困境

Markdown 已成为技术文章的事实标准格式。它轻量、易读、可渲染为多种形式(如 HTML、PDF、知识库页面),因而广泛用于技术文档、博客和学术笔记。然而,当我们希望智能体(Agent)自动审阅、改写或生成 Markdown 文档时,却会发现它在这一环节表现往往不够理想:

  • • 结构混乱:Agent 在插入或修改章节时容易破坏文档层级;
  • • 格式丢失:修改后代码块闭合符、列表缩进常被破坏;
  • • 语义模糊:难以区分正文、注释和示例代码;
  • • 上下文不连贯:对章节间逻辑关系缺乏理解。

根本原因在于——Markdown 是一种纯文本标记语言,结构靠符号隐式表达,语义依赖渲染器解析。对于智能体而言,它看到的只是文本行,并不真正“理解”哪些是章节、哪些是代码或表格。

要让智能体能像编辑器或 IDE 一样高效、安全地操作 Markdown,我们需要在它与文本之间引入一个结构化层,使文档语义可感知、可操控。这正是“结构化解析与语义编辑方案”的核心思想。

项目地址:https://github.com/ForceInjection/markdown-mcp

原文地址:https://github.com/ForceInjection/markdown-mcp/blob/main/docs/markdown-agent.md

相关文章:从零构建 MCP 服务:为 TRAE IDE 添加智能 Markdown TOC 处理能力


二、Markdown 的结构与语义挑战

Markdown 的简洁性带来了灵活性,也带来了歧义。其结构单元包括:

  • • 层级化元素:标题、列表、引用;
  • • 块级内容:段落、代码块、表格;
  • • 内联元素:强调、链接、行内代码;
  • • 语义表达相对隐晦的格式:缩进、空行、标点变体。

同一语义结构可以有多种写法:

1. 列表项
   -
 子项

或

- 列表项
  -
 子项

两者渲染效果相同,但文本结构不同。这种不确定性使得智能体难以通过简单字符串匹配完成语义修改。
此外,Markdown 的上下文依赖性(如标题级别决定章节归属、列表嵌套依赖缩进)进一步增加了智能体理解与编辑的难度。


三、核心思路:结构化中间表示(SIR)与方案选择

3.1 实现方案对比

实现方案思路优点局限
AST(抽象语法树)
使用 Markdown 解析器构建语法树(如 remark、markdown-it)
结构精确、生态成熟
需了解语法节点类型
JSON IR
将 AST 序列化为 JSON,供 Agent 直接读取
易与 API/LLM 交互,清晰直观
格式化细节可能丢失
HTML/DOM
转 Markdown → HTML → DOM 结构
可复用浏览器生态、编辑可视化
Markdown 语义部分丢失
双向模型(AST + Source Map)
同时保存 AST 与原文映射
可逆性高,支持增量修改
实现复杂度较高

方案说明:

  • • AST(抽象语法树):通过标准 Markdown 解析器构建精确的语法结构,适合需要精确控制文档结构的场景
  • • JSON IR:将 AST 序列化为 JSON 格式,便于与 API 和 LLM 交互,适合需要跨平台数据交换的场景
  • • HTML/DOM:利用浏览器生态进行可视化编辑,适合需要富文本编辑功能的场景
  • • 双向模型(AST + Source Map):同时保留结构化表示和原文映射,提供完整的可逆性保证

从技术实现角度来看,AST 和 JSON IR 都是可行的技术路径,它们能够提供结构化的文档表示。但在实际智能体应用场景中,我们选择了更完善的双向模型(AST + Source Map) 方案,因为它提供了完整的可逆性保证和原文映射能力。

3.2 SIR 的核心概念与原理

3.2.1 SIR 的定义与目标

SIR(Structured Intermediate Representation)是一个语义化的中间表示层,它充当了智能体与原始 Markdown 文本之间的桥梁。为了解决智能体在纯文本上操作的脆弱性,需要在 Markdown 与自然语言之间引入这个结构化中间层。

其核心思想是:

  • • 语义抽象:将 Markdown 的文本符号转换为具有明确语义的节点对象
  • • 结构层次化:构建树状结构来反映文档的层级关系
  • • 操作安全化:提供语义级别的编辑接口,避免直接文本操作

3.2.2 SIR 的作用机制

SIR 的作用类似于:

  • • HTML 中的 DOM:提供结构化的文档对象模型,支持精确的节点操作
  • • 程序语言中的抽象语法树(AST):将源代码转换为可分析的树结构
  • • 数据库中的模式定义(Schema):定义文档结构的规范和约束

它将 Markdown 文档转换为一棵语义树,使智能体可以像操作数据结构一样编辑文档节点,而不直接修改文本。

3.2.3 SIR 的结构化表示

在语义层,文档可被视为一棵结构化的树:

Document (根节点)
├── Heading(level=1, text="引言")           ← 一级标题节点
│   └── Paragraph("Markdown 的流行与挑战...") ← 段落子节点
├── Heading(level=2, text="结构化中间表示")   ← 二级标题节点
│   ├── Paragraph("SIR 的定义与目标...")     ← 段落子节点
│   └── CodeBlock(language="python", content="...") ← 代码块子节点
└── Heading(level=2, text="实现方案")        ← 另一个二级标题节点
    ├── List(type="unordered")              ← 无序列表节点
    │   ├── ListItem("方案一:AST 解析")      ← 列表项
    │   └── ListItem("方案二:JSON IR")       ← 列表项
    └── Table()                            ← 表格节点
        ├── TableRow(["方案", "优点"])       ← 表头行
        └── TableRow(["AST", "结构精确"])     ← 数据行

3.2.4 SIR 的工作原理

SIR 的工作流程遵循以下核心原则:

  1. 1. 解析阶段:将原始 Markdown 文本解析为抽象语法树(AST)
  2. 2. 转换阶段:将 AST 转换为语义化的 SIR 节点树
  3. 3. 操作阶段:智能体通过语义接口操作 SIR 节点
  4. 4. 渲染阶段:将修改后的 SIR 节点树重新渲染为 Markdown 文本

这种分层架构确保了:

  • • 操作安全性:所有编辑都在结构化层面进行,避免文本级错误
  • • 语义明确性:每个节点都有明确的类型和语义含义
  • • 可逆性保证:通过源代码映射实现精确的文本位置跟踪

3.3 为什么选择 SIR 方案?

基于对上述方案的深入分析和实际项目需求,我们最终选择了双向模型(AST + Source Map) 作为 SIR 的实现方案,主要原因如下:

3.3.1 技术优势

  1. 1. 完整的可逆性保证:通过源代码映射,能够精确追踪每个 SIR 节点对应的原始文本位置,支持精确的撤销/重做操作
  2. 2. 语义完整性:既保留了 AST 的结构精确性,又通过 SIR 提供了更高层次的语义抽象
  3. 3. 操作安全性:所有编辑操作都在结构化层面进行,避免了直接文本操作的风险

3.3.2 智能体友好性

  1. 1. 接口语义化:提供 update_heading、insert_section 等语义明确的编辑接口,而非低级的文本操作
  2. 2. 上下文感知:SIR 节点包含完整的层级关系信息,智能体可以理解章节之间的逻辑关系
  3. 3. 错误预防:结构化操作自动处理格式细节(如缩进、闭合符),避免人为错误

3.3.3 工程实践考量

  1. 1. 扩展性:模块化设计支持轻松添加新的节点类型和编辑操作
  2. 2. 可维护性:清晰的架构分层使得各组件职责明确,易于维护和调试
  3. 3. 性能优化:支持增量更新和选择性渲染,提高大规模文档处理效率

3.3.4 与替代方案的对比优势

  • • 相比纯 AST:提供了更高层次的语义抽象,更适合智能体理解
  • • 相比 JSON IR:保持了源代码映射能力,支持精确的位置追踪
  • • 相比 HTML/DOM:保留了 Markdown 特有的语义信息,不会丢失原始格式

3.4 本章小结

SIR 方案的核心价值在于实现了从文本编辑到语义编辑的范式转变:

  1. 1. 智能体不再需要理解 Markdown 语法细节,只需关注文档的语义结构
  2. 2. 编辑操作变得意图明确且安全可靠,避免了格式破坏的风险
  3. 3. 支持复杂的结构化操作,如章节移动、内容重组、格式批量更新
  4. 4. 提供了完整的编辑历史追踪,支持精确的撤销和版本控制

这种方案特别适合需要自动化处理技术文档的场景,如:

  • • 智能文档审校和格式化
  • • 自动化章节重组和编号
  • • 多语言文档同步更新
  • • 技术文档知识图谱构建

通过 SIR 方案,我们为智能体提供了既安全又强大的 Markdown 编辑能力,真正实现了"让智能体像人类编辑一样理解和操作文档"的目标。


四、具体实现:Python SIR 框架

基于上述理论,我们实现了一个完整的 Python SIR 框架,位于 src/markdown_editor/ 目录下。该框架采用双向模型(AST + Source Map) 实现,提供了完整的结构化编辑能力。

4.1 架构概览

                    +-----------------------+
                    |   Semantic Editor     |  ← 智能体调用语义接口
                    +-----------------------+
                             ↓ ↑
                    +-----------------------+
                    |   Structured IR       |  ← 内存中的语义树表示
                    +-----------------------+
                             ↓ ↑
+-------------+     +-----------------------+     +-------------+
| Markdown    |  →  |   Parser & Converter  |  →  | Markdown    |
| (Text Input)|     +-----------------------+     | (Text Output)|
+-------------+     |  - AST Parser         |     +-------------+
                    |  - SIR Converter      |
                    |  - Source Mapper      |
                    +-----------------------+

文件结构:

markdown_editor/
├── sir_schema.py      # SIR 节点类型定义(数据模型层)
├── ast_parser.py      # Markdown → AST 解析器(解析层)
├── sir_converter.py   # AST → SIR 转换器(转换层)
├── semantic_editor.py # 语义编辑接口(业务逻辑层)
├── sir_renderer.py    # SIR → Markdown 渲染器(渲染层)
├── source_map.py      # 源代码映射管理(基础设施层)
└── __init__.py        # 模块导出(API 层)

4.2 SIR Schema 设计

在 sir_schema.py 中定义了完整的 SIR 节点类型,采用 TypedDict 和枚举实现:

class NodeType(str, Enum):
    """SIR 节点类型枚举"""

    DOCUMENT = "document"
    SECTION = "section"
    HEADING = "heading"
    PARAGRAPH = "paragraph"
    CODE_BLOCK = "code_block"
    LIST = "list"
    LIST_ITEM = "list_item"
    TABLE = "table"
    TABLE_ROW = "table_row"
    TABLE_CELL = "table_cell"
    BLOCKQUOTE = "blockquote"
    HR = "hr"
    HTML_BLOCK = "html_block"
    INLINE = "inline"

class
 HeadingLevel(int, Enum):
    """标题级别枚举"""

    H1 = 1
    H2 = 2
    H3 = 3
    H4 = 4
    H5 = 5
    H6 = 6

class
 SIRNode(TypedDict):
    """SIR 节点基础接口"""

    id
: str
    type
: NodeType
    content: Optional[str]
    children: List['SIRNode']
    attributes: Dict[str, Any]
    source_location: Optional[SourceLocation]
    parent_id: Optional[str]

class
 HeadingNode(SIRNode):
    """标题节点"""

    type
: Literal[NodeType.HEADING]
    level: HeadingLevel
    title: str
    anchor: Optional[str]
    auto_number: Optional[str]

class
 SIRDocument(TypedDict):
    """完整的 SIR 文档表示"""

    metadata: SIRMetadata
    ast: SIRNode
    source_map: Dict[str, SourceLocation]
    errors: List[Dict[str, Any]]
    warnings: List[Dict[str, Any]]

4.3 解析与转换流程

框架采用两阶段处理:

  1. 1. AST 解析 (ast_parser.py): 使用 markdown-it-py 构建标准 AST
  2. 2. SIR 转换 (sir_converter.py): 将 AST 转换为语义化的 SIR
# 完整处理流程
def
 process_markdown(content: str) -> SIRDocument:
    # 1. 解析为 AST

    ast_parser = MarkdownASTParser()
    ast_root = ast_parser.parse(content)

    # 2. 转换为 SIR

    sir_converter = SIRConverter()
    sir_document = sir_converter.convert(ast_root)

    # 3. 生成源代码映射

    source_mapper = SourceMapper(content)
    source_mapper.build_mapping(sir_document)

    return
 sir_document

4.4 语义编辑接口

在 semantic_editor.py 中定义了丰富的语义操作:

class EditOperation(str, Enum):
    """编辑操作类型枚举"""

    UPDATE_HEADING = "update_heading"
    INSERT_SECTION = "insert_section"
    DELETE_SECTION = "delete_section"
    MOVE_SECTION = "move_section"
    UPDATE_CONTENT = "update_content"
    ADD_PARAGRAPH = "add_paragraph"
    ADD_CODE_BLOCK = "add_code_block"
    ADD_LIST = "add_list"
    ADD_TABLE = "add_table"
    RENUMBER_HEADINGS = "renumber_headings"
    FIX_NUMBERING = "fix_numbering"
    CHECK_CONSISTENCY = "check_consistency"
    AUTO_REPAIR = "auto_repair"

class
 EditPosition(str, Enum):
    """编辑位置枚举"""

    BEFORE = "before"
    AFTER = "after"
    CHILD = "child"
    REPLACE = "replace"

@dataclass

class
 EditResult:
    """编辑操作结果"""

    success: bool
    message: str
    changes: List[Dict[str, Any]]
    warnings: List[str]
    errors: List[str]

class
 SemanticEditor:
    """语义化编辑器"""


    def
 __init__(self, sir_document: SIRDocument, config: Optional[SIRConfig] = None):
        self
.document = sir_document
        self
.config = config or SIRConfig()
        self
.edit_history: List[Dict[str, Any]] = []
        self
.source_map: Optional[SourceMap] = None

    def
 update_heading(self, node_id: str, new_title: str,
                      new_level: Optional[int] = None
) -> EditResult:
        """更新标题内容和/或级别"""

        # 实现细节...


    def
 insert_section(self, parent_id: str, position: EditPosition,
                      title: str, level: int = 2, content: Optional[str] = None
) -> EditResult:
        """插入新的章节"""

        # 实现细节...


    def
 delete_section(self, node_id: str) -> EditResult:
        """删除指定章节"""

        # 实现细节...

4.5 源代码映射与可逆性

source_map.py 实现了精确的源代码位置跟踪:

class SourceMapper:
    def
 build_mapping(self, sir_document: SIRDocument):
        """构建 SIR 节点到原始文本的映射"""

        for
 node in traverse_sir(sir_document):
            if
 node.source_location:
                self
._mapping[node.id] = node.source_location

    def
 get_original_text(self, node_id: str) -> str:
        """获取节点对应的原始文本"""

        location = self._mapping[node_id]
        return
 self.original_content[location.start_line:location.end_line]

4.6 高级特性

框架还提供了以下高级功能:

  • • 自动编号重排: 修改标题级别时自动重新编号
  • • 锚点生成: 为标题生成唯一的 URL 锚点
  • • 编辑历史: 支持撤销/重做操作
  • • 批量操作: 支持原子性的多步编辑
  • • 一致性验证: 编辑后验证 Markdown 语法正确性

4.7 完整使用示例

以下示例展示了从解析到编辑的完整流程,使用当前实际的 API 接口:

from markdown_editor import (
    create_editor_from_markdown,
    EditPosition,
    EditOperation
)

# 原始 Markdown 内容

original_markdown = """
# 项目介绍

这是一个技术文档项目,旨在解决智能体编辑 Markdown 的挑战。

## 当前功能

- 基础解析
- 简单编辑

## 技术架构

项目采用模块化设计。
"""


print
("=== 初始文档 ===")
print
(original_markdown)

# 创建语义编辑器

editor = create_editor_from_markdown(original_markdown)

# 1. 更新现有标题

print
("\n=== 更新标题 ===")
result1 = editor.update_heading(
    node_id="heading_2",  # "当前功能"标题的ID
    new_title="已实现功能",
    new_level=2
)
print
(f"更新结果: {result1.success}")

# 2. 插入新的章节

print
("\n=== 插入新章节 ===")
result2 = editor.insert_section(
    parent_id="section_1",  # "项目介绍"章节
    position=EditPosition.CHILD,
    title="设计目标",
    level=3,
    content="""
本项目旨在提供:
1. 安全的结构化编辑
2. 精确的源代码映射
3. 丰富的语义操作接口
"""

)
print
(f"插入结果: {result2.success}")

# 3. 获取编辑历史

print
("\n=== 编辑历史 ===")
for
 i, edit in enumerate(editor.edit_history):
    print
(f"{i+1}. {edit['operation']}")

# 渲染最终结果

final_markdown = editor.render()
print
("\n=== 最终文档 ===")
print
(final_markdown)

输出结果:

# 项目介绍

这是一个技术文档项目,旨在解决智能体编辑 Markdown 的挑战。

### 设计目标


本项目旨在提供:

1.
 安全的结构化编辑
2.
 精确的源代码映射
3.
 丰富的语义操作接口

## 已实现功能


-
 基础解析
-
 简单编辑
-
 高级语义操作
-
 源代码映射
-
 一致性验证

## 技术架构


项目采用模块化设计。

4.8 测试与验证

项目包含完整的测试套件,确保功能正确性和稳定性:

# 运行所有测试
pytest tests/ -v

# 运行编辑器相关测试

pytest tests/editor/ -v
pytest tests/test_semantic_editor.py -v

# 运行目录提取相关测试

pytest tests/toc/ -v
pytest tests/test_toc_mcp_server.py -v

# 运行 MCP 服务器测试

pytest tests/test_editor_mcp_server.py -v
pytest tests/test_toc_mcp_server.py -v

# 生成测试覆盖率报告

pytest --cov=src/markdown_editor tests/ --cov-report=html

测试覆盖以下关键场景:

  • • 各种 Markdown 语法的正确解析
  • • 语义编辑操作的正确执行(插入、更新、删除等)
  • • 目录提取和生成功能
  • • MCP 服务器接口的正确性
  • • 边界情况和错误处理
  • • 中文内容和特殊字符的处理

4.9 本章小结

本章详细介绍了基于 Python 的 SIR 框架实现,该框架具有以下核心优势:

  1. 1. 完整的结构化表示:通过双向模型(AST + Source Map)实现了精确的文档结构表示和源代码映射
  2. 2. 丰富的语义接口:提供了覆盖常见编辑场景的语义操作,包括标题更新、章节插入删除、内容替换等
  3. 3. 强大的可逆性保证:基于源代码映射实现了精确的撤销/重做和位置追踪能力
  4. 4. 模块化架构设计:采用清晰的层次结构,各组件职责明确,易于维护和扩展
  5. 5. 类型安全保障:使用 Python dataclass 和 Enum 确保类型正确性和代码健壮性
  6. 6. 测试验证完善:包含完整的测试套件,覆盖编辑器功能和目录提取功能
  7. 7. MCP 集成支持:与 MCP 服务器架构完美集成,支持智能体调用

该实现完全遵循了前文所述的结构化编辑理念,为智能体提供了既安全又强大的 Markdown 文档操作能力,真正实现了从文本编辑到语义编辑的范式转变。


五、功能示例:智能体重写技术章节

5.1 智能体编辑场景

以下是一些典型的智能体编辑场景,通过自然语言与智能体交互:

场景 1:文档重构

请帮我重新组织文档结构,将第5个标题的层级改为2级,并在"项目介绍"章节下插入一个三级标题"重组后的结构",内容为"重新组织后的文档内容..."。

场景 2:内容扩展

请扩展技术文档,在"架构设计"章节下插入一个三级标题"性能优化",内容包含:
通过以下技术实现性能优化:
1. 缓存机制
2. 懒加载策略
3. 并行处理

同时将"实现"标题更新为"详细实现"并保持二级标题。

场景 3:错误修复

请修复文档中的错误:
1. 将"错误标题"的层级修正为3级
2. 将"格式错误的标题"更新为"正确的标题"并保持2级标题

5.2 智能体重写示例

假设原文如下:

## 实验结果

以下展示模型在不同参数下的性能。

智能体交互指令:

请在'实验结果'章节后追加一段分析结论,内容为"综合来看,模型在中等参数下表现最稳定。"

智能体执行后的结果:

## 实验结果

以下展示模型在不同参数下的性能。

综合来看,模型在中等参数下表现最稳定。

整个过程通过自然语言指令完成,智能体自动处理 Markdown 解析、节点定位、内容插入和格式保持,避免了手动字符串操作可能造成的格式错误。


六、总结与展望

Markdown 的开放性让人类写作变得轻松,却给机器编辑带来了巨大挑战。要让智能体真正具备技术文档的"理解与编辑"能力,关键在于从纯文本处理过渡到结构化表示层。通过构建结构化中间表示(SIR)并提供语义化操作接口,智能体可以安全、精确地修改文档内容,实现从传统的"文本编辑"到现代的"语义编辑"的根本性转变。

展望未来,这一技术思路具有广阔的扩展空间:

  • • 自动化文档审校与一致性检查:基于 SIR 实现智能化的文档质量评估
  • • 技术文档知识图谱生成:从结构化文档中提取知识关系网络
  • • 多模态协作编辑:支持文本、图表、代码块等多种元素的协同处理

实施说明:当前实现仍处于 MVP(最小可行产品)阶段,后续需要与 IDE 文本编辑器深度整合,并解决手工编辑文档时如何高效更新 SIR 等关键技术问题。