技术博客的图表公式:如何让复杂公式和图解协同讲清一个技术概念
2026/7/19 16:07:59 网站建设 项目流程

技术博客的图表公式:如何让复杂公式和图解协同讲清一个技术概念

一、深度引言与场景痛点

大家好,我是赵咕咕。

作为一个写了两年技术博客的工程师,我深知一个痛点:有些技术文章读完之后,你既没看懂、也没记住,唯一的收获是"这篇的作者好像很厉害"。

问题通常出在信息密度和可理解性的失衡上。纯文字描述一个分布式共识算法,读者脑子里的状态机要同时跑 N 个节点、M 条消息,认知负荷直接拉满。但如果只放一张图没有文字说明,图的细节又无法被准确传达。

好的技术文章,公式、图、文字三种媒介是协同的关系,不是堆砌的关系。公式定义精确规则,图展示整体结构,文字连接两者并给出直觉解释。

这篇文章不讲某个具体技术,而是分享我两年写技术博客过程中总结出的一套方法论——如何用公式和图协同讲清楚一个技术概念

二、底层机制与原理深度剖析

2.1 三种媒介的认知分工

人脑处理不同类型信息时调用不同的认知通道:

  • 文字走"序列加工"通道:一个字一个字地读,适合描述因果逻辑和操作步骤。
  • 公式走"符号推理"通道:精确、无歧义,适合定义规则和描述数学关系。但认知负荷极高,大部分人读到第三个符号脑子就开始飘。
  • 图形走"并行加工"通道:一眼就能看到整体结构和关键关系。适合展示架构、流程和状态转换。但对细节精度天生不敏感。

三种媒介就像三个配合不佳的队友:图告诉你"这里有一堆盒子",公式告诉你"盒子之间怎么算",文字告诉你"为什么要这么算"。任何一方缺席,整个解释体系就会塌。

2.2 图-公式-文字协同模型

为了实现图、公式、文字的高效协同,我们可以将一个复杂的技术概念按照以下结构进行拆解与串联:

  1. 第一阶段:三维度概念拆解

    • 核心关系提取:提炼出技术概念中的关键节点、流向以及相互之间的依赖关系。
    • 数学规则定义:推导出该概念的计算公式、数学约束以及边界条件。
    • 直觉经验解释:理清设计的初衷是什么(Why)、具体该如何运作(How)以及有哪些避坑细节。
  2. 第二阶段:多媒介精确表达

    • 架构拓扑(图解):通过流程图或架构图直观展示系统整体的架构和节点流向。
    • 精确行为(公式/代码):用严格的数学公式或核心代码片段定义确定的系统行为。
    • 桥梁连接(文字叙述):用通俗的文字叙述去承接和补充图与公式。
  3. 第三阶段:图文联合标注

    • 映射绑定:在图表中标注说明,确保“图中的节点”与“公式中的变量”能够一一映射。
    • 直觉闭环:最终让读者体验到“图给直觉 → 公式给精确 → 文字给路径”的无缝理解闭环。

协同的核心原则是每一个公式符号都在图中有对应节点,每一段文字都在图和公式之间架桥

举个例子。假设你要写一篇文章解释 Transformer 中的注意力机制。纯公式写法是这样的:

[
\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
]

然后就开始逐项解释 Q、K、V 是什么、d_k 是什么、为什么要除以 sqrt(d_k)。这种写法的问题是:读者看不到"钱流向哪"。Q、K、V 是三个矩阵,它们之间怎么交互的?计算图长什么样?

好的写法应该是:先放一张图展示 Q、K、V 的流动,然后在图的旁边标注"这里的 Q×K^T 就是求相似度矩阵,softmax 就是归一化成概率,乘以 V 就是加权求和"。公式放在下面作为精确的数学定义。文字在中间解释"为什么这样做"——比如"除以 sqrt(d_k) 是为了防止点积过大导致 softmax 梯度消失"。

三者在同一段内容中协同出现,读者先看图建立直觉,再看公式验证直觉,最后看文字理解设计意图。

三、生产级代码实现

这里不是"写代码",而是给出一个可复用的图表-公式-文字模板生成器。它可以帮你快速生成 Mermaid 图与公式标注的 Markdown 块:

import asyncio from dataclasses import dataclass, field from typing import Any @dataclass class DiagramNode: """图中的节点定义。""" id: str label: str formula_symbol: str | None = None # 对应的公式符号 description: str = "" @dataclass class DiagramEdge: """图中的边定义。""" source: str target: str label: str = "" formula_relation: str | None = None # 对应公式中的什么运算 @dataclass class TechDiagram: """技术图表的完整描述。""" title: str diagram_type: str # flowchart / sequence / classDiagram / stateDiagram nodes: list[DiagramNode] = field(default_factory=list) edges: list[DiagramEdge] = field(default_factory=list) formulas: list[str] = field(default_factory=list) narrative: str = "" def render_mermaid(self) -> str: """生成 Mermaid 图代码。""" lines = [f"```mermaid", f"{self.diagram_type}"] for node in self.nodes: lines.append(f" {node.id}[{node.label}]") for edge in self.edges: arrow = f" {edge.source} -->{edge.label and f'|{edge.label}|' or ''} {edge.target}" lines.append(arrow) lines.append("```") return "\n".join(lines) def render_formula_annotation(self) -> str: """生成公式-图中节点的对照表。""" lines = ["| 公式符号 | 图中节点 | 含义 |", "|---------|---------|-----|"] for node in self.nodes: if node.formula_symbol: lines.append( f"| `{node.formula_symbol}` | [{node.label}] | {node.description} |" ) return "\n".join(lines) def render_full_section(self) -> str: """生成完整的"图-文字-公式"协同章节。""" parts = [f"### {self.title}\n"] # 文字叙述 parts.append(self.narrative + "\n") # 图 parts.append(self.render_mermaid() + "\n") # 公式标注表 parts.append(self.render_formula_annotation() + "\n") # 公式 for f in self.formulas: parts.append(f"$$\n{f}\n$$\n") return "\n".join(parts) class BlogOutlineGenerator: """技术博客大纲生成器:自动生成图-公式-文字的协同结构。""" def __init__(self, llm): self._llm = llm async def generate_diagram( self, concept: str, context: str = "" ) -> TechDiagram: """根据技术概念自动生成图表的骨架描述。""" prompt = f"""你是一个技术写作助手。请分析以下技术概念,并提取出核心元素。 技术概念: {concept} 补充上下文: {context} 请以 JSON 格式返回以下内容: {{ "diagram_type": "flowchart 或 sequence 或 stateDiagram", "nodes": [ {{"id": "节点ID", "label": "节点名称", "formula_symbol": "公式中对应的符号(可选)", "description": "节点的含义说明"}} ], "edges": [ {{"source": "起点ID", "target": "终点ID", "label": "边标注", "formula_relation": "对应公式中的运算(可选)"}} ], "formulas": ["LaTeX 公式1", "LaTeX 公式2"], "narrative": "一段 150-200 字的直觉解释,用工程师的口吻,轻松直白" }} 只返回 JSON,不要其他内容。""" try: import json response = await self._llm.generate(prompt) content = response.content if hasattr(response, "content") else str(response) content = content.strip().removeprefix("```json").removesuffix("```").strip() data = json.loads(content) return TechDiagram( title=f"{concept}的核心架构", diagram_type=data.get("diagram_type", "flowchart"), nodes=[DiagramNode(**n) for n in data.get("nodes", [])], edges=[DiagramEdge(**e) for e in data.get("edges", [])], formulas=data.get("formulas", []), narrative=data.get("narrative", ""), ) except Exception as e: # 降级为手动构建 return TechDiagram( title=concept, diagram_type="flowchart", narrative=f"(自动生成失败: {e},请手动构建图表)", ) async def validate_diagram( self, diagram: TechDiagram ) -> list[str]: """验证图表是否满足"可理解性"标准。""" issues: list[str] = [] # 规则 1:每个公式符号都必须有对应的节点 symbols_in_formulas = set() for f in diagram.formulas: import re for match in re.finditer(r'\b([A-Za-z_]\w*)\b', f): sym = match.group() if sym not in ('text', 'frac', 'sum', 'sqrt', 'softmax', 'max', 'min'): symbols_in_formulas.add(sym) node_symbols = { n.formula_symbol for n in diagram.nodes if n.formula_symbol } unmatched = symbols_in_formulas - node_symbols if unmatched: issues.append(f"公式中的符号未在图中标注: {unmatched}") # 规则 2:每个节点都应该有描述 nodes_without_desc = [n.id for n in diagram.nodes if not n.description] if nodes_without_desc: issues.append(f"以下节点缺少描述: {nodes_without_desc}") # 规则 3:每张图至少有一条 narrative 文字 if len(diagram.narrative) < 50: issues.append("图的文字解释过短,建议至少 100 字") return issues # ─── 写作检查清单 ─── WRITING_CHECKLIST = [ "☐ 每张 Mermaid 图旁边有至少 3 句文字解释", "☐ 图中的每个节点在文字中至少被提及 1 次", "☐ 公式中的每个符号都有对应的图中节点", "☐ 公式所在段落前有至少 1 句直觉解释", "☐ 图文关系标注(对照表或文中引用)", "☐ 图的粒度适中:一张图讲一个概念,不要试图一张图讲所有", ] # ─── 常见模式库 ─── COMMON_PATTERNS = { "请求-响应流程": { "diagram_type": "sequenceDiagram", "template": """sequenceDiagram participant C as Client participant S as Server participant DB as Database C->>S: 发送请求 S->>DB: 查询数据 DB-->>S: 返回结果 S-->>C: 响应""", }, "系统架构": { "diagram_type": "flowchart TB", "template": """flowchart TB A[请求入口] --> B[业务逻辑层] B --> C[数据访问层] C --> D[数据库] B --> E[缓存层] E --> F[Redis]""", }, "状态转换": { "diagram_type": "stateDiagram-v2", "template": """stateDiagram-v2 [*] --> Idle Idle --> Processing: 收到请求 Processing --> Success: 处理完成 Processing --> Error: 异常 Error --> Idle: 重置 Success --> [*]""", }, } async def main(): print("技术博客图表公式协同写作工具箱") print("=" * 50) print() # 示例:解释 RAG 检索流程 rag_diagram = TechDiagram( title="RAG 检索流程", diagram_type="flowchart LR", nodes=[ DiagramNode("Q", "Query", "Q", "用户查询向量"), DiagramNode("D", "Doc Index", "D", "文档向量索引"), DiagramNode("S", "Similarity", "S", "相似度计算"), DiagramNode("R", "Top-K", "TopK", "检索结果"), ], edges=[ DiagramEdge("Q", "S", "输入", "cos(Q, D)"), DiagramEdge("D", "S", "输入", "cos(Q, D)"), DiagramEdge("S", "R", "排序取 Top-K", "argmax"), ], formulas=[ "S(d) = \\frac{Q \\cdot d}{\\|Q\\| \\|d\\|} \\quad \\forall d \\in D", "R = \\text{TopK}_{d \\in D}\\; S(d)", ], narrative=( "RAG 检索的本质是在向量空间中找邻居。你把用户问题变成一个向量 Q," "然后在文档向量池 D 里遍历,计算每个文档 d 跟 Q 的余弦相似度 S(d)。" "拿 Top-K 个最像的文档,这就是检索结果 R。关键就在于两点:Q 的质量" "(用户意图捕获得准不准)和 D 的覆盖率(有没有包含相关知识)。" ), ) print(rag_diagram.render_full_section()) print() print("## 写作检查清单") for item in WRITING_CHECKLIST: print(item) if __name__ == "__main__": asyncio.run(main())

工具集的设计思路

  • TechDiagram是核心抽象:一个结构体同时描述图节点、公式符号和文字叙述,强制三者关联。
  • validate_diagram自动检查常见问题:公式符号没标注、节点缺描述、文字解释过短。
  • COMMON_PATTERNS提供常见模式的 Mermaid 模板,覆盖 80% 的技术写作场景,不需要每次从零画图。
  • BlogOutlineGenerator是 AI 辅助生成器,从技术概念自动提取图结构。但当前 LLM 生成的图结构质量一般,建议作为草稿起点,人工精修后再用。

四、边界分析与架构权衡

4.1 一张图讲一件事 vs 一张图讲所有

这是我见过最多的错误:一张流程图上密密麻麻塞了 20 个节点、15 条边、5 种颜色、3 个图例。Mermaid 渲染出来之后读者需要放大 300% 才能看清。

一张图只讲一个概念。如果概念包含多个子概念,拆成多张图。用文字作为图之间的过渡桥梁。

反例:用户看到一张图里有向量检索、BM25 检索、重排序、嵌入缓存、结果合并……大脑直接过载。正例:第一张图画"检索流程的三阶段",第二张图画"每个阶段内部的子步骤"。

4.2 公式的展示粒度

不是所有技术文章都需要公式。判断标准:公式是否在解释过程中被直接引用?

如果一篇文章里放了一个公式但后面再也没有提到它,删掉它。如果文章用文字描述了"除以 sqrt(d_k) 是为了避免梯度消失",那配一个公式来说明具体怎么除的,就是有价值的。

4.3 图的类型选择

Mermaid 支持多种图类型,每种有它最擅长的表达:

图类型最适合不适合
flowchart架构、数据流、决策树时间顺序
sequenceDiagramAPI 调用序列、协议交互并行关系
stateDiagram状态机、生命周期数据流动
classDiagram代码结构、类关系动态行为
erDiagram数据库关系过程描述

选错类型是常见的图表问题。比如用 flowchart 画 API 调用序列,箭头方向混乱。用 sequenceDiagram 画架构图,participant 越来越多导致横向空间爆炸。

4.4 可访问性与导出

CSDN 对 Mermaid 的支持总体不错,但有些 CDN 加载慢的场景可能需要把 Mermaid 导出为 SVG 图片作为 fallback。mermaid-climmdc命令)可以将.mmd文件转为 SVG/PNG。

公式方面,CSDN 使用 MathJax 渲染 LaTeX。注意不要用太冷门的 LaTeX 包——MathJax 只支持 AMSmath 核心子集。

五、总结

技术博客写作中,图、公式、文字是三件套。三者不是独立的,而是互相标注、互相解释、互相增强的关系。

实操建议:

  1. 先画图,再写文。图是概念的骨架,画清楚图之后,文章的叙述自然就出来了。
  2. 图-公式对照。用 Markdown 表格建立公式符号到图中节点的映射,这是降低认知负荷最有效的手段。
  3. 一张图一个点。别怕图多。5 张简洁的小图比 1 张复杂的大图好理解 10 倍。
  4. 公式前先给直觉。在贴 LaTeX 之前,用一句白话解释"这个公式在算什么"。让读者带着预期去读公式。
  5. 用工具检查。写完后跑一遍validate_diagram,看看有没有公式符号没在图里标注、节点有没有缺描述。

好的技术文章不是"把代码和公式贴上来就行",而是要让读者在读完的瞬间产生一种"Aha! 原来是这样的"的感觉。而图-公式-文字的黄金三角,就是制造这种"Aha moment"最可靠的配方。


下一篇预告:收官之作——Agent 系统全年架构演进总结,从单体 Agent 到多 Agent 平台的完整路线图。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询