<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://fiction.spaplex.org/</id>
  <title type="text">Oblivion Scape</title>
  <subtitle type="text">Fiction Melody</subtitle>
  <updated>2026-09-01T00:00:00.000Z</updated>
  <author><name>Akatsuki Sky</name></author>
  <link rel="alternate" href="https://fiction.spaplex.org/"/>
  <link rel="self" href="https://fiction.spaplex.org/atom.xml"/>
  <generator uri="https://github.com/CuteLeaf/Firefly">Firefly v6.16.8</generator>
    <entry>
      <id>https://fiction.spaplex.org/posts/rag/</id>
      <title type="text">RAG 检索增强生成：原理、架构与工程实践</title>
      <published>2026-09-01T00:00:00.000Z</published>
      <updated>2026-09-01T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/rag/"/>
      <summary type="text">系统剖析 RAG 的两大核心支柱：离线索引（Indexing）与在线检索生成流程，以及分块、Embedding 与 Rerank 工程实践</summary>
      <content type="html"><![CDATA[<section><h2>一、Why RAG<a href="#一why-rag"><span>#</span></a></h2><p>LLM 自身的知识有三个根本性限制：<strong>训练截止日期之后的事它不知道；私有数据它没见过；它无法溯源</strong>。这些限制不是模型能力问题，是机制问题——知识被固化在训练好的权重里，推理时不变化，每次回答既无法引用来源，也无法即时更新。</p><p>针对这三个痛点，2020 年 Patrick Lewis 等人在 Meta FAIR 提出的 <strong>Retrieval-Augmented Generation（RAG）</strong> 给出了一套解决方案：<strong>不修改模型权重，而是在推理时把”相关的外部知识”动态注入到 context 中</strong>。模型读到这些被检索来的内容，基于它们生成回答。从工程上看，RAG 把模型的知识分成了两部分：<strong>参数化记忆（权重）+ 非参数化记忆（外部数据库）</strong>。前者负责语言能力，后者负责具体事实。</p><p>RAG 之所以成为生成式 AI 应用的事实标准，是因为它同时解决了三个根本问题。<strong>知识时效性</strong>：训练截止后的信息可以通过外部索引实时注入；<strong>私有数据接入</strong>：企业内部文档无需进入训练流程就能被模型使用；<strong>幻觉与可溯源性</strong>：模型回答可附上引用，便于追溯和验证。这三件事任何一件单独成立都足以让 RAG 成为必备能力，三件事叠加在一起就成了所有企业 AI 应用的基础设施。</p><p>要理解 RAG 在工程上由哪些环节组成、为什么 embedding 和 indexing 是它的两大支柱、为什么经典 RAG 已经不够用、为什么 Anthropic 和 Microsoft 走出了三种不同的演进路线，前提是搞清楚：<strong>一段外部文档如何被预处理、如何被检索、如何被注入到 context 中</strong>。</p></section>
<section><h2>二、RAG 与 Context 的关系<a href="#二rag-与-context-的关系"><span>#</span></a></h2><p>RAG 本质上是 context 管理的一种工程手段。RAG 是其中专门用来解决”跨会话长期记忆”和”超出 context 容量的大知识库”的方案。它跟其他方案的关系不是替代，而是互补——长会话场景用 Compaction 压缩历史，跨会话场景用 RAG 检索相关内容，工具调用密集场景用 Subagent 隔离。</p><p>理解这一点之后，RAG 的所有设计都能从 context 视角解释。<strong>为什么要分块（chunking）</strong>：因为整篇文档塞不进 context；<strong>为什么要做语义检索</strong>：因为只能塞几个最相关的块，必须挑准；<strong>为什么要 rerank</strong>：因为粗筛回来的候选还有噪声，挑得不够准会浪费 context 预算；<strong>为什么要 contextual retrieval</strong>：因为分块切断了原文的语境，光看孤立块连相关性都判断不准。整套 RAG 就是围绕”如何用最少的 token 把最相关的知识塞进 context”展开的工程优化。</p></section>
<section><h2>三、RAG 的工作流总览<a href="#三rag-的工作流总览"><span>#</span></a></h2><p>一套完整的 RAG 系统在工程上分为两个独立子流程：<strong>离线索引（Indexing）</strong> 与 <strong>在线查询（Retrieval + Generation）</strong>。两者在时间、成本、性能要求上完全不同——离线索引可能耗时数小时甚至数天，但只做一次；在线查询必须在数百毫秒内完成，且每次提问都触发。这是 RAG 系统设计的核心时间约束。</p><div><div><div><div><span><p>在线查询</p></span></div><div><span><p>离线索引</p></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>原始文档</p></span></div><div><span><p>分块<br /><br />Chunking</p></span></div><div><span><p>Embedding 模型</p></span></div><div><span><p>向量数据库</p></span></div><div><span><p>用户查询</p></span></div><div><span><p>Embedding 模型</p></span></div><div><span><p>Top-K Chunks</p></span></div><div><span><p>拼装 Prompt</p></span></div><div><span><p>生成模型</p></span></div><div><span><p>回答 + 引用</p></span></div>
</div><div><div><span><p>在线查询</p></span></div><div><span><p>离线索引</p></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>原始文档</p></span></div><div><span><p>分块<br /><br />Chunking</p></span></div><div><span><p>Embedding 模型</p></span></div><div><span><p>向量数据库</p></span></div><div><span><p>用户查询</p></span></div><div><span><p>Embedding 模型</p></span></div><div><span><p>Top-K Chunks</p></span></div><div><span><p>拼装 Prompt</p></span></div><div><span><p>生成模型</p></span></div><div><span><p>回答 + 引用</p></span></div>
</div></div></div><p>有一条硬性约束必须明确：<strong>离线与在线必须使用同一个 embedding 模型</strong>。不同模型生成的向量位于不同的几何空间，互相之间没有可比性。一旦切换 embedding 模型，所有历史索引必须重新生成。这是 RAG 工程中常被低估、但代价极高的一条铁律。</p></section>
<section><h2>四、Embedding：把语义变成可计算的向量<a href="#四embedding把语义变成可计算的向量"><span>#</span></a></h2><p>RAG 的整个工作机制建立在一个核心数学操作上——<strong>把文字变成可以比较的数字</strong>。这个操作叫 embedding。理解 embedding 是理解 RAG 的前提。</p><section><h3>4.1 直觉<a href="#41-直觉"><span>#</span></a></h3><p>LLM 处理文字时，从来不是直接读字符。文字必须先转换成数字才能被神经网络处理。但更进一步的问题是：<strong>如何让数字之间的”距离”反映文字之间的”语义相似性”</strong>？</p><p>举一个具体例子，下面三句话：</p><ul>
<li>A：「我喜欢猫」</li>
<li>B：「我爱小猫咪」</li>
<li>C：「今天股市大跌」</li>
</ul><p>人类直觉立刻能判断 A 和 B 语义接近、A 和 C 几乎无关。但要让计算机做同样判断，必须找一种数学表示，使 A 和 B 对应的”东西”在数学上很接近、A 和 C 对应的”东西”在数学上很远。</p><p>Embedding 就是这种表示。每段文字被映射为一个<strong>固定长度的浮点数列表</strong>（叫向量），向量之间的几何距离反映文字的语义距离。例如这三句话的 embedding 大致如下（实际维度通常 1024 或 1536，这里简化为 5 维）：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>A: [0.21, -0.45, 0.88,  0.12, -0.33]</span></div></div><div><div><div>2</div></div><div><span>B: [0.23, -0.42, 0.85,  0.15, -0.30]   ← 跟 A 数值非常接近</span></div></div><div><div><div>3</div></div><div><span>C: [-0.61, 0.32, -0.17, 0.91,  0.44]   ← 跟 A 数值差很远</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>得到向量之后，“语义相似度”就变成了向量之间的几何距离问题——纯数学。</p></section><section><h3>4.2 两种”Embedding”，不要搞混<a href="#42-两种embedding不要搞混"><span>#</span></a></h3><p>这里要立刻澄清一个被严重混用的术语。AI 圈说的”embedding”实际指代两件完全不同的东西。<strong>第一种是 LLM 内部的 token embedding</strong>——LLM 输入层有一张巨大的查找表（embedding matrix），把每个 token ID 映射为一个向量，这是 O(1) 的查表操作，几乎不消耗算力，存在于 LLM 内部不可单独使用。<strong>第二种是 RAG 使用的 sentence/text embedding</strong>——它是一个完全独立的小型神经网络，输入一段文本，输出一个表示整段语义的向量，是要跑完整前向传播的真实模型，消耗算力、按 token 收费。RAG 中说的 embedding 指第二种。两者唯一的共同点是产物都叫”向量”，但生成机制、用途、成本完全不同。</p>

<table><thead><tr><th>维度</th><th>LLM 内部 Token Embedding</th><th>独立 Embedding 模型（RAG 用）</th></tr></thead><tbody><tr><td>本质</td><td>一张查找表</td><td>一个独立神经网络</td></tr><tr><td>输入</td><td>1 个 token ID</td><td>一段文本</td></tr><tr><td>输出</td><td>1 个向量（每 token 一个）</td><td>1 个向量（整段压缩）</td></tr><tr><td>操作</td><td>O(1) 查表</td><td>完整前向传播</td></tr><tr><td>算力</td><td>几乎为零</td><td>真实消耗（远小于 LLM）</td></tr><tr><td>是否可独立使用</td><td>否</td><td>是</td></tr></tbody></table><p>后面讲的 embedding 模型、训练方式、cosine similarity，全部指第二种。</p></section><section><h3>4.3 Embedding 模型<a href="#43-embedding-模型"><span>#</span></a></h3><p>负责把文字转成向量的，是一个独立的小型神经网络，叫 <strong>embedding 模型</strong>。</p><p>它跟前面提到的 LLM 是<strong>两个完全独立的模型</strong>——不要混淆。LLM 的任务是”读完一段输入预测下一个字”，输出是文字；embedding 模型的任务是”读完一段文字输出一个能代表语义的向量”，输出是数字。两者训练目标、模型结构、API 调用、计费方式都独立。</p>

<table><thead><tr><th>维度</th><th>LLM</th><th>Embedding 模型</th></tr></thead><tbody><tr><td>任务</td><td>生成下一个 token</td><td>把文本压成一个向量</td></tr><tr><td>输出</td><td>文字</td><td>浮点数组</td></tr><tr><td>大小</td><td>几十亿到万亿参数</td><td>几千万到几亿参数</td></tr><tr><td>API 调用</td><td><code>chat.completions</code></td><td><code>embeddings.create</code></td></tr><tr><td>计费</td><td>输入输出 token 分别计费</td><td>仅按输入 token 计费</td></tr></tbody></table><p>主流商用 embedding 模型：OpenAI 的 <code>text-embedding-3-small</code>（输出 1536 维向量）与 <code>text-embedding-3-large</code>（3072 维）；Voyage AI 的 <code>voyage-3</code>（1024 维，Anthropic 官方推荐）以及代码、金融、法律等领域专用版本；开源方向有 BGE、E5 系列。<strong>成本极低</strong>——OpenAI <code>text-embedding-3-small</code> 大约 $0.02 / 百万 tokens，几万页文档才花一美元。所以在 RAG 的总成本中，embedding 这部分小到可以忽略。</p></section><section><h3>4.4 Embedding 模型如何”学会”<a href="#44-embedding-模型如何学会"><span>#</span></a></h3><p>Embedding 模型的训练原理是 <strong>对比学习（contrastive learning）</strong>。训练时把数据组织成成对的形式：</p><ul>
<li>正样本对：「猫睡在沙发上」和「沙发上的猫在打盹」 → 训练目标是让两者向量<strong>靠近</strong></li>
<li>负样本对：「猫睡在沙发上」和「股市今天大跌」 → 训练目标是让两者向量<strong>远离</strong></li>
</ul><p>跑几亿对这种数据，模型自然学会”什么叫语义接近”。注意这里学到的”语义”完全是统计性的——模型没有任何人类意义上的理解，它只是发现「猫」「打盹」「沙发」这些词高频共现，所以认为它们语义接近。这套思想可以追溯到 2013 年 Mikolov 等人在 Google 提出的 Word2Vec——他们最早证明了”语义关系在向量空间中具有线性结构”（著名的 <code>king − man + woman ≈ queen</code>），这一发现奠定了后续所有 embedding 工程的基础。</p></section><section><h3>4.5 如何比较两个向量：Cosine Similarity<a href="#45-如何比较两个向量cosine-similarity"><span>#</span></a></h3><p>得到向量之后，比较”相似度”用的最常见公式是 <strong>余弦相似度（cosine similarity）</strong>。它的核心思想是：<strong>只看两个向量的方向是否一致，不看长度</strong>。</p><ul>
<li>方向完全一致 → cosine = 1（最相似）</li>
<li>完全垂直 → cosine = 0（无关）</li>
<li>方向相反 → cosine = -1（语义对立）</li>
</ul><p>为什么用 cosine 不用直线距离？因为<strong>文本长度不应影响语义判断</strong>——“猫”这一个字和”我家有一只可爱的小花猫”应该被判定为相关，但它们的向量模长差异可能很大。Cosine 自动忽略长度差异，只比较”方向”，正好符合需求。</p><p>整个 RAG 检索的数学本质，就是<strong>算用户问题的向量和库内每个文档片段向量的 cosine，取分数最高的几个</strong>。这一对比环节在工程上叫 <strong>similarity search</strong>，向量数据库内部用 HNSW、IVF 等 ANN（近似最近邻）算法实现，能在毫秒级从百万级向量中找出 Top-K。</p></section><section><h3>4.6 把 Embedding 在 RAG 中的位置标清楚<a href="#46-把-embedding-在-rag-中的位置标清楚"><span>#</span></a></h3><p>回到 RAG 视角，embedding 出现在两个时刻：</p><div><div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>建库时<br /><br />每段文档</p></span></div><div><span><p>Embedding 模型</p></span></div><div><span><p>向量<br /><br />(存进库里)</p></span></div><div><span><p>提问时<br /><br />用户问题</p></span></div><div><span><p>Embedding 模型<br /><br />(必须同一个)</p></span></div><div><span><p>向量<br /><br />(用来检索)</p></span></div>
</div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>建库时<br /><br />每段文档</p></span></div><div><span><p>Embedding 模型</p></span></div><div><span><p>向量<br /><br />(存进库里)</p></span></div><div><span><p>提问时<br /><br />用户问题</p></span></div><div><span><p>Embedding 模型<br /><br />(必须同一个)</p></span></div><div><span><p>向量<br /><br />(用来检索)</p></span></div>
</div></div></div><p>注意一条硬性规则：<strong>建库与提问必须用同一个 embedding 模型</strong>。不同模型生成的向量位于不同的几何空间，互相之间没有可比性。一旦切换 embedding 模型，所有历史索引必须全量重新生成。这是 RAG 工程中常被低估、但代价极高的一条铁律。</p></section><section><h3>4.7 Embedding 的局限<a href="#47-embedding-的局限"><span>#</span></a></h3><p>虽然 embedding 是 RAG 的核心，但它有几个根本性的弱点必须明确。
<strong>第一，否定词容易被稀释</strong>——「我喜欢猫」和「我不喜欢猫」的 cosine 相似度通常很高，因为「不」这个字对整段向量影响有限。这导致 RAG 在精确性场景下天然脆弱。
<strong>第二，精确字符串匹配能力弱</strong>——产品代码、错误码（如 <code>0x80070005</code>）、人名、SKU 这类信息会被压进”通用区域”，向量检索难以命中。
<strong>第三，跨领域迁移弱</strong>——通用 embedding 模型在医疗、法律、代码等垂直领域表现明显下降，因此有 <code>voyage-code</code>、<code>voyage-finance</code> 等领域版本。
<strong>第四，有损压缩</strong>——把一段千字内容压成 1024 个数字，必然丢细节，embedding 擅长抓”主题与整体语义”，但精确事实、数字、专有名词容易被压糊。</p><p>这些弱点决定了 embedding 不能单独用，必须搭配其他检索手段。这就引出了下一个关键名词——BM25。</p></section><section><h3>4.8 BM25：基于关键词的另一条检索路线<a href="#48-bm25基于关键词的另一条检索路线"><span>#</span></a></h3><p><strong>BM25</strong> 是一种基于关键词匹配的检索算法，全称 Best Matching 25，1994 年由 Stephen Robertson 提出，是 Elasticsearch、Lucene、OpenSearch 等传统搜索引擎的底层默认评分函数。它跟 embedding 完全是两套思路。</p><p>BM25 的工作原理一句话概括：<strong>统计查询中的每个关键词在文档中出现的频率，结合文档长度做归一化，给出相关性分数</strong>。它不理解语义，只看字面匹配。例如用户查询 <code>ACME 2023 Q2 营收</code>，BM25 会扫描所有文档，找出同时包含 “ACME”、“2023”、“Q2”、“营收” 这些字面词的文档，按出现频率打分排序。</p><p><strong>BM25 的强项</strong>正是 embedding 的弱项：</p><ul>
<li><strong>精确专有名词</strong>：错误码、SKU、人名、产品名——字面命中即可</li>
<li><strong>罕见词</strong>：训练语料里少见的术语，embedding 没学好，BM25 直接字面匹配</li>
<li><strong>数字、日期、代号</strong>：embedding 容易把它们压进通用区域，BM25 字面匹配</li>
</ul><p><strong>BM25 的弱项</strong>正是 embedding 的强项：</p><ul>
<li><strong>同义改写</strong>：用户问”加速训练”，文档写”提升收敛速度” → BM25 完全失效</li>
<li><strong>跨语言</strong>：用户用中文问，文档是英文 → BM25 完全失效</li>
<li><strong>概念性查询</strong>：用户问”如何优化性能”，需要语义理解</li>
</ul><p>两者的盲区互补，这就是<strong>为什么实战 RAG 一定要同时跑 embedding 和 BM25 两条路线</strong>。这种做法叫 <strong>hybrid search（混合检索）</strong>。WANDS 电商基准测试显示，单独 BM25 与单独向量检索的检索质量几乎相同，但<strong>两者合并后整体提升约 7.4%</strong>，因为它们各自捞回的结果有大量互补。</p><p>到这里，embedding、cosine similarity、BM25、hybrid search 几个核心名词都有了基础，下一节讲它们如何被组装成完整的索引和检索流程。</p></section></section>
<section><h2>五、Indexing：把文档预处理好放进库里<a href="#五indexing把文档预处理好放进库里"><span>#</span></a></h2><p>RAG 不是把整篇文档原封不动塞进数据库就完事了——文档必须经过<strong>一整套预处理流程</strong>才能被高效检索。这套流程叫 <strong>indexing（建索引）</strong>。</p><section><h3>5.1 三个概念的关系再次澄清<a href="#51-三个概念的关系再次澄清"><span>#</span></a></h3><ul>
<li><strong>Embedding</strong> 是一种<strong>技术</strong>——把文字变成向量</li>
<li><strong>Indexing</strong> 是一个<strong>工程动作</strong>——把文档预处理后存进数据库</li>
<li><strong>RAG</strong> 是一种<strong>应用范式</strong>——检索 + 生成</li>
</ul><p>三者<strong>层层包含</strong>：RAG 使用 indexing 的成果；indexing 使用 embedding 作为工具之一。但三者并不是绑定关系——indexing 不一定只用 embedding（关键词索引也是 indexing），embedding 也不只用于 RAG（推荐、聚类、异常检测都能用）。</p></section><section><h3>5.2 Indexing 的四个步骤<a href="#52-indexing-的四个步骤"><span>#</span></a></h3><p>Indexing 在工程上分为四步，每一步都有独立的工程权衡。</p><div><div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>原始文档<br /><br />PDF / MD / HTML</p></span></div><div><span><p>Step 1<br /><br />解析为纯文本</p></span></div><div><span><p>Step 2<br /><br />切成小块<br /><br />Chunking</p></span></div><div><span><p>Step 3<br /><br />生成向量<br /><br />Embedding</p></span></div><div><span><p>Step 4<br /><br />写入数据库<br /><br />(向量库 + 关键词索引)</p></span></div>
</div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>原始文档<br /><br />PDF / MD / HTML</p></span></div><div><span><p>Step 1<br /><br />解析为纯文本</p></span></div><div><span><p>Step 2<br /><br />切成小块<br /><br />Chunking</p></span></div><div><span><p>Step 3<br /><br />生成向量<br /><br />Embedding</p></span></div><div><span><p>Step 4<br /><br />写入数据库<br /><br />(向量库 + 关键词索引)</p></span></div>
</div></div></div><p><strong>Step 1 — 解析为纯文本</strong>。原始文档可能是 PDF、Word、Markdown、HTML，要先转成纯文本字符串。对结构化内容这一步特别麻烦——PDF 中的扫描页需要 OCR、表格需要结构还原、双栏排版需要识别阅读顺序。这是 RAG 系统最容易掉链子的环节。主流工具：<code>unstructured</code>、<code>docling</code>、Azure Document Intelligence。这一步消耗 CPU 但不消耗 LLM token，成本极低。</p><p><strong>Step 2 — Chunking（切块）</strong>。把长文本切成小块（chunk），这是 RAG 工程中最被低估的环节。原因很简单：模型 context 装不下整篇文档，必须切成小块按需取用；同时 embedding 模型本身也有输入长度上限。但切多大才合适？这是个权衡：</p><ul>
<li><strong>chunk 太小</strong>（&lt; 100 tokens）→ 单块语义不完整，孤立看不明所以</li>
<li><strong>chunk 太大</strong>（&gt; 1000 tokens）→ 单块包含多个主题，向量会”模糊”</li>
<li><strong>业界经验值</strong>：200–800 tokens 区间，叠加 10–20% 滑窗重叠</li>
</ul><p>不同类型内容有不同切块策略。普通文本可以按段落或固定长度切；代码必须按函数 / 类边界切，跨边界会破坏语法结构；表格整张表必须作为一个 chunk，按行切会失去列头语境；Markdown 应该按 <code>#</code> <code>##</code> 等标题层级切。<strong>这一步同样不消耗 token，纯字符串操作</strong>。</p><p><strong>Step 3 — 生成向量（Embedding）</strong>。每个 chunk 喂给 embedding 模型，得到一个向量。这一步是真实的神经网络推理，消耗 token，<strong>但 embedding 模型便宜</strong>——按百万 tokens 计的成本只有几美分。</p><p><strong>Step 4 — 写入数据库</strong>。chunk 文本和对应向量<strong>必须一起存</strong>——向量用于检索，文本用于注入到 prompt 中。如果只存向量，检索到了也不知道对应的原文是什么。同时如果走 hybrid search 路线，还要把 chunk 文本写一份进 BM25 倒排索引（这是 Elasticsearch / OpenSearch / Lucene 这类传统搜索引擎的标准能力，几乎零成本）。</p></section><section><h3>5.3 向量数据库简介<a href="#53-向量数据库简介"><span>#</span></a></h3><p>存向量的数据库叫<strong>向量数据库（vector database）</strong>。它跟传统数据库的关键差异是：传统数据库擅长精确查找（“找出 ID = 123 的记录”），向量数据库擅长<strong>相似度查找</strong>（“找出与这个向量 cosine 最高的 20 个记录”）。后者在百万级数据上做暴力计算需要几秒到几十秒，向量数据库内部用 <strong>ANN 算法（Approximate Nearest Neighbor，近似最近邻）</strong> 把这一过程压到毫秒级。主流 ANN 算法有 HNSW、IVF，原理不展开——使用者不需要懂，调用 API 即可。</p><p>主流向量数据库：Pinecone、Qdrant、Weaviate、Chroma（独立产品）；pgvector（PostgreSQL 扩展）；Azure AI Search、Vertex AI Vector Search（云服务托管）。选型主要看托管成本、可扩展性、是否需要自部署，技术能力上各家差异不大。</p></section><section><h3>5.4 Indexing 的成本结构<a href="#54-indexing-的成本结构"><span>#</span></a></h3><p>Indexing 阶段的成本以 embedding 模型调用为主，但因为 embedding 极便宜（百万 tokens 仅 $0.02），对几百万 tokens 量级的知识库做一次全量 indexing 通常只需几美分到几美元。<strong>Indexing 这个动作本身——切块、入库、查表——完全不消耗 token</strong>，是纯 CPU/IO 操作。所以 RAG 成本优化的重点从来不在 indexing 上，而在<strong>运行时的主 LLM 调用</strong>上。</p></section><section><h3>5.5 Indexing 之后：库里到底有什么<a href="#55-indexing-之后库里到底有什么"><span>#</span></a></h3><p>一次完整的 indexing 完成后，数据库里存的东西大致是这样：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>向量库（用于 embedding 检索）</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>┌─────────────────────────────────────────────────┐</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>│ chunk_001  →  向量 [0.21, -0.45, ...]            │</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>│             ↳  原文 "公司的收入比上一季度..."     │</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>│ chunk_002  →  向量 [0.18, -0.42, ...]            │</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>│             ↳  原文 "本季度推出了新产品..."       │</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>│ ...                                              │</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>└─────────────────────────────────────────────────┘</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>BM25 倒排索引（用于关键词检索）</span></div></div><div><div><div>11</div></div><div><span><span>  </span></span><span>┌─────────────────────────────────────────────────┐</span></div></div><div><div><div>12</div></div><div><span><span>  </span></span><span>│ 词 "ACME"  →  出现在 [chunk_001, chunk_015, ...] │</span></div></div><div><div><div>13</div></div><div><span><span>  </span></span><span>│ 词 "营收"  →  出现在 [chunk_001, chunk_008, ...] │</span></div></div><div><div><div>14</div></div><div><span><span>  </span></span><span>│ 词 "Q2"    →  出现在 [chunk_001, chunk_022, ...] │</span></div></div><div><div><div>15</div></div><div><span><span>  </span></span><span>│ ...                                              │</span></div></div><div><div><div>16</div></div><div><span><span>  </span></span><span>└─────────────────────────────────────────────────┘</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>注意两个库存的是<strong>同一批 chunk 的两种不同视图</strong>——一个按”语义指纹”组织，一个按”出现的关键词”组织。提问时两路都要查，再合并结果。这就是 hybrid search 的物理基础。</p></section></section>
<section><h2>六、经典 RAG 的根本缺陷：上下文丢失<a href="#六经典-rag-的根本缺陷上下文丢失"><span>#</span></a></h2><p>到这里为止讲的是 2024 年之前所谓的”经典 RAG”。</p><p>这一方法在 2024 年遭遇了严重的挑战——Anthropic 在 9 月发布的博文 <em>Introducing Contextual Retrieval</em> 中明确指出了它的系统性缺陷：<strong>传统 RAG 在编码信息时移除了上下文，导致系统无法从知识库中检索到本应相关的信息</strong>。</p><p>Anthropic 给出的经典例子是这样的：某金融知识库中存在一个 chunk，原文是「公司的收入比上一季度增长了 3%」。当用户查询「ACME 公司在 2023 年第二季度的收入增长是多少？」时，<strong>这个 chunk 既不会被向量检索命中</strong>（embedding 里没有 ACME、2023、Q2 这些语义信号），<strong>也不会被 BM25 命中</strong>（关键词零重叠）。但从整篇文档角度看它显然就是答案——只是分块时切断了 chunk 与上下文的关联，让它失去了识别度。</p><p>这是经典 RAG 的系统性问题。任何长文档分块后都会出现大量”丢上下文”的 chunk——技术报告里写”该方法相比 baseline 提升了 5%“，但具体是哪个方法、哪个 baseline 在前文；财报里写”营业利润同比增长 12%“，但具体是哪家公司、哪个季度也在前文。分块切断了这些信息，孤立的 chunk 就失去了被检索到的能力。</p></section>
<section><h2>七、三种应对方法：chunk 层、query 层、context 层<a href="#七三种应对方法chunk-层query-层context-层"><span>#</span></a></h2><p>针对这个问题，业界三家头部厂商给出了三种完全不同的应对方法。</p><p><strong>Anthropic 的 chunk 层修复：Contextual Retrieval</strong>。在 embedding 之前，用 LLM 为每个 chunk 生成 50-100 tokens 的”上下文化前缀”，描述该 chunk 在全文中的位置与背景。原始 chunk「公司的收入比上一季度增长了 3%」会被改写为「本段来自 ACME 公司 2023 Q2 SEC 10-Q 文件的财务摘要部分；上一季度营收为 3.14 亿美元。公司的收入比上一季度增长了 3%」。上下文化后的 chunk 才进入 embedding 与 BM25 索引——这样 chunk 自带 ACME、2023、Q2 等关键词，向量也带上了这些语义信号。这一步要对每个 chunk 调一次 LLM 处理整篇文档加该 chunk，听起来昂贵，但通过 prompt caching（整篇文档只缓存一次，每个 chunk 只为变化部分付费），总成本可压到约 <code>$1 / 百万文档 tokens</code>。Anthropic 给出的实测数据是惊人的：Contextual Embeddings 单独使用让检索失败率降低 35%，叠加 Contextual BM25 降低 49%，再叠加 reranking 降低 <strong>67%</strong>。这是当前最具影响力的方案，已被业界广泛复现。<strong>注意</strong>：Claude 这里生成的”小型上下文”是<strong>一段普通文字</strong>，不是向量、不是 embedding，它只是给 chunk 补全了文字，后续才走标准的 embedding 流程。这是非常容易被混淆的一点。</p><p><strong>Microsoft / Azure 的 query 层修复：Agentic Retrieval</strong>。不在 chunk 层做手脚，而是前置增强 query 的智能化——用 LLM 在查询前做 query rewriting、query decomposition、并行子查询。Azure AI Search 2025 年 5 月推出的 Agentic Retrieval 把这套做成了官方能力：LLM 分析复杂问题，分解为多个针对性子查询，跨知识源并行执行，再融合结果。复杂查询的相关性比经典 RAG 提升最高 40%。Copilot Studio 的 4 步流水线也是同样的哲学：用最近 10 轮对话上下文重写查询、从所有已配置知识源各取 Top 3、生成带引用的回答、内容审核。</p><p><strong>Google 的 context 层跳过：超大窗口直接全文塞入</strong>。Gemini 2.5 Pro 支持 1M tokens 的原生 context，对于较小的知识库（百万 tokens 以内），Google 的建议是<strong>跳过 RAG，直接全文塞 context</strong>。这种做法完全无信息丢失、工程最简单，代价是受限于 context rot（前面讲过的”长 context 上模型悄悄变笨”）和容量上限。Anthropic 也认可这一方案：知识库小于 200K tokens 时可省略 RAG。</p><p>成熟的 RAG 系统往往三者并用。Azure AI Search 的 Agentic Retrieval 同时做 query decomposition 与 hybrid search；Claude Projects 在容量内时全文塞 context，超过时自动触发 RAG；企业级方案往往在 Anthropic 的 Contextual Retrieval 基础上叠加 query rewriting。</p></section>
<section><h2>八、2026 年的标准 RAG 技术栈<a href="#八2026-年的标准-rag-技术栈"><span>#</span></a></h2><p>把前面讲的所有改进组合起来，2026 年企业级 RAG 的事实标准已经形成：<strong>Contextual Chunks + Hybrid Search（BM25 + Vector） + RRF 融合 + Cross-encoder Reranking + Agentic Query Decomposition</strong>。任何企业级 RAG 项目都应以此为起点而非从经典 RAG 起步。各环节单独失效率降幅可叠加：Contextual Retrieval 降 49%、Reranker 再降 18%、Agentic Retrieval 再降相关性 40%——综合下来比 2020 年的经典 RAG 强出数倍。</p><p>下表总结各方案的特征：</p>

<table><thead><tr><th>方案</th><th>信息损失</th><th>实现复杂度</th><th>何时启用</th></tr></thead><tbody><tr><td>经典 RAG</td><td>高</td><td>低</td><td>MVP / 小知识库</td></tr><tr><td>Hybrid Search + RRF</td><td>中</td><td>中</td><td>含专有名词 / 错误码场景</td></tr><tr><td>+ Reranker</td><td>低</td><td>中</td><td>追求高精度场景</td></tr><tr><td>+ Contextual Retrieval</td><td>极低</td><td>高</td><td>大型企业知识库</td></tr><tr><td>+ Agentic Retrieval</td><td>极低</td><td>极高</td><td>复杂多步问题场景</td></tr></tbody></table></section>
<section><h2>九、Agentic RAG：从一次性检索到工具化检索<a href="#九agentic-rag从一次性检索到工具化检索"><span>#</span></a></h2><p>经典 RAG 是一次性的：“检索一次 → 拼装 prompt → 生成回答”。这在简单 Q&amp;A 上有效，但在复杂任务上有明显局限：复杂问题需要多步检索（先查 A，根据 A 的结果再查 B）；检索结果可能自相矛盾需要澄清；单次检索的 chunk 可能缺失关键背景。</p><p><strong>Agentic RAG</strong> 把检索本身视为 Agent 可调用的工具，由模型决定何时检索、检索什么、是否继续检索。代表实现是 Claude Code 的 Agentic Search——它<strong>不预先 embedding 代码库</strong>，而是让 Agent 用 grep / glob / read 等工具按需探索代码，每一步都是模型自主决策。GitHub Copilot Chat 走同样的思路：对 GitHub 仓库有远端 semantic code search index 兜底，但实际交互中大量依赖工具调用（grep、file search、find references、read），本质是 Agentic Search 而非经典 RAG。这是 2025-2026 年代码类 Agent 的核心转变。</p><p>OpenAI File Search、Anthropic Claude Projects、Microsoft 365 Copilot 也都在向 Agentic RAG 方向演进——检索从”一次性预处理步骤”转为”Agent 可重复调用的工具”。模型可以决定”我需要更多信息，再检索一次”，可以决定”这次检索结果不够用，换个角度再查”。</p></section>
<section><h2>十、RAG 的真实成本结构<a href="#十rag-的真实成本结构"><span>#</span></a></h2><p>把 RAG 的所有环节成本放到一起对比，得到一张非常重要的全景图。假设 100 万 tokens 的文档库，不同方案的成本对照：</p>

<table><thead><tr><th>方案</th><th>Indexing 一次成本</th><th>单次问答成本</th><th>检索质量</th></tr></thead><tbody><tr><td>全文塞 context（不用 RAG）</td><td><code>$0</code></td><td><code>$5</code>（按 GPT-5 输入价）</td><td>100% 但 context rot</td></tr><tr><td>经典 RAG</td><td><code>$0.02</code></td><td><code>$0.05</code></td><td>baseline</td></tr><tr><td>Contextual Retrieval</td><td><code>$1</code></td><td><code>$0.05</code></td><td>失败率 ↓ 49%</td></tr><tr><td>Contextual + Reranker</td><td><code>$1</code></td><td><code>$0.06</code></td><td>失败率 ↓ 67%</td></tr></tbody></table><p>三个核心观察。
<strong>第一</strong>，indexing 成本随方案不同差 50-500 倍，但绝对值都很小——花一次性的小钱换长期检索质量提升，工程上完全划算。
<strong>第二</strong>，运行时成本主要由 LLM 决定，跟用不用 contextual retrieval 关系不大。
<strong>第三</strong>，主 LLM 推理（约 <code>$0.05/次</code>）远高于 indexing 任何阶段。结论是<strong>优化 RAG 成本先看主 LLM 的输入 token 怎么省</strong>——Top-K 减小、chunk 缩短、用更便宜的生成模型——indexing 阶段那点钱不用纠结。</p></section>
<section><h2>十一、终端产品中的 RAG 实现<a href="#十一终端产品中的-rag-实现"><span>#</span></a></h2><p>终端 LLM 产品在 RAG 上的策略差异非常大，分清楚有助于理解日常工具的真实行为。</p><p><strong>Claude Projects</strong> 当 Project 的知识库逼近上下文窗口上限时<strong>自动切换到 RAG 模式</strong>，将容量扩展约 10 倍，无需用户配置。界面会显示 “Indexing” 提示告知当前模式。容量回落到 context 容量内时自动切回 in-context 模式。Anthropic API 层面则提供完整的 Contextual Retrieval 实现。</p><p><strong>ChatGPT Projects</strong> 提供工作区语义的 RAG 体验——每个 Project 拥有独立的文件库、自定义指令、聊天历史。OpenAI File Search Tool 是其 API 层暴露：用户预先创建 vector store 并上传文件，OpenAI 自动完成解析、分块、embedding、索引，调用时模型决定是否检索、检索什么，返回结果包含 file citations 引用。OpenAI 的”上下文丢失”方案不做 chunk 层 contextual prefix，而是依赖<strong>语义化分块策略 + 混合检索 + 元数据 attribution</strong>。</p><p><strong>Microsoft 365 Copilot</strong> 的 RAG 不依赖用户上传——它直接基于 <strong>Microsoft Graph + Semantic Index</strong> 检索企业现有数据（SharePoint、OneDrive、Outlook、Teams、日历、Planner、Loop、Viva、Graph Connectors 外部系统）。2026 年推出的 <strong>Work IQ</strong> 是组织智能层，超越了传统的文档式 RAG——它聚合带权限的工作信号而非原始文档（邮件模式、会议关系、文档协作模式、任务归属、非正式团队关系），构建持久化的工作记忆（个人沟通风格、重复工作流、常合作的同事、角色优先级）。<strong>Copilot Studio</strong> 在中间层提供四步 RAG 流水线（query rewriting、content retrieval、summarization、safety validation），底层是 <strong>Azure AI Search</strong>——它在 2025 年 5 月推出的 Agentic Retrieval 把”query 层修复”做成了产品能力。</p><p><strong>Google Vertex AI</strong> 按抽象层级分三个产品：<strong>Vertex AI Search</strong> 完全托管，开箱即用语义+关键词混合搜索；<strong>Vertex AI RAG Engine</strong> 中等托管，提供 RAG 流水线编排；<strong>Vertex AI Vector Search</strong> 最底层向量数据库服务。Google 的 grounding 体系还包括 <strong>Grounding with Google Search</strong>——直接把 Gemini 回答 grounded 到实时搜索结果。</p>

<table><thead><tr><th>产品</th><th>RAG 类型</th><th>自动激活</th><th>上下文丢失方案</th></tr></thead><tbody><tr><td>Claude Projects</td><td>自动触发 RAG</td><td>容量达上限时</td><td>内置 Contextual Retrieval</td></tr><tr><td>Anthropic API</td><td>开发者自建</td><td>需手动实现</td><td>Contextual + Hybrid + Reranker</td></tr><tr><td>ChatGPT Projects</td><td>文件库式 RAG</td><td>上传即生效</td><td>语义分块 + 混合检索</td></tr><tr><td>OpenAI File Search API</td><td>托管 vector store</td><td>需手动建库</td><td>语义分块 + Hybrid Search</td></tr><tr><td>M365 Copilot</td><td>Graph-grounded RAG</td><td>全自动</td><td>Semantic Index + Work IQ</td></tr><tr><td>Copilot Studio</td><td>多源 RAG</td><td>配置后自动</td><td>4 步流水线</td></tr><tr><td>Azure AI Search</td><td>经典 + Agentic</td><td>可选</td><td>Agentic Retrieval（提升 40%）</td></tr><tr><td>Vertex AI Search</td><td>高度托管</td><td>全自动</td><td>内置语义+关键词混合</td></tr></tbody></table></section>
<section><h2>十二、PDF 上传与 Copilot 问代码库的真实行为<a href="#十二pdf-上传与-copilot-问代码库的真实行为"><span>#</span></a></h2><p>把 RAG 知识应用到日常工具行为上，几个常见场景值得明确。</p><p><strong>拖 PDF 进 chatbot 问问题</strong>的行为取决于文件大小。小 PDF（几十页内）会被全文塞 context，完全不走 RAG；大 PDF 自动触发 RAG，Claude.ai 切换时会显式显示 “Indexing”，ChatGPT 隐式切换不提示。判断当前模式的方法是问模型”统计全文 X 出现几次”——答得准说明全文塞入，答得近似说明走了 RAG。各家阈值不同：ChatGPT 大约 50-100 页内全文塞入，Claude 200 页内，Gemini 由于 1M context 几乎不需要触发 RAG。</p><p><strong>VS Code 里 GitHub Copilot 问代码库</strong>用的是分层 fallback 机制。文件数 &lt; 100 且 &lt; 32K tokens 时全部塞 context；GitHub 仓库自动触发<strong>远端 semantic code search index</strong>（真正的经典 RAG，GitHub 服务端用专门的代码 embedding 模型预建索引，跨用户共享）；非 GitHub 本地仓库可选 local index 上限 2500 文件；Agent 模式组合 grep / file search / read 等工具按需检索，本质是 <strong>Agentic Search</strong>。</p><p><strong>IntelliJ IDEA 里的 Copilot</strong> 是简化版——命令是 <code>@project</code> 而非 VS Code 的 <code>@workspace</code>，<strong>没有独立 embedding 索引</strong>，依赖 IDE 自身的 PSI 索引 + 文本搜索。对 md 文件的检索质量明显弱于 VS Code，实战中推荐用 <code>#filename</code> 或 <code>#folder/</code> 显式指定上下文，绕过它薄弱的自动检索环节。这也是为什么主问答留在 VS Code、IntelliJ 只做 Java 开发是当前最务实的分工。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/agent-knowledge/</id>
      <title type="text">Knowledge：Agent 里的知识检索机制与架构</title>
      <published>2026-08-31T00:00:00.000Z</published>
      <updated>2026-08-31T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/agent-knowledge/"/>
      <summary type="text">解析 Agent 体系中 Knowledge 的本质定位、与 Context 和 Skill 的关系，以及知识外挂注入工程</summary>
      <content type="html"><![CDATA[<blockquote><p>整理时间：2026-08-31</p></blockquote>
<hr />
<section><h2>一、Knowledge 是什么<a href="#一knowledge-是什么"><span>#</span></a></h2><p>提到 Agent 的 Knowledge，容易望文生义地以为它是某种被写进协议里的标准能力，像 OAuth 有规范文档、<a href="/posts/MCP/">MCP</a> 有 Anthropic 发布的协议规格。</p><p>事实并非如此——<strong>“Knowledge” 从来不是一个有正式规范的技术术语，它是各家产品和框架各自起的功能性名字</strong>：Claude 把它叫 project knowledge，OpenAI 把它叫 knowledge files / vector store，Gemini 把它叫 File Search，开源 Agent 框架（LangChain、LlamaIndex）则统一叫它 RAG（Retrieval-Augmented Generation）。没有任何组织出面定义”Knowledge 必须长什么样”，这也是它和 MCP 最大的不同——MCP 有协议文档规定”外部工具怎么被标准化调用”，Knowledge 没有对应的东西，各家实现可以完全不兼容，甚至同一家公司不同产品线的做法都不一样。</p><p>剥掉命名的外壳，Knowledge 的技术内核只有一句话：<strong>模型参数之外、运行时可检索的外部信息源</strong>。模型的”知识”在训练阶段就已经固化进权重，而 Knowledge 指的是训练之后、通过工程手段外挂进来的信息，本质就是 RAG 那一套。</p><p>Knowledge 与 Skill 是同一层面的两种东西：都是在运行时往上下文里注入内容，但注入的东西性质不同。<strong>Skill 注入的是”指令”——一份 SOP、一套操作步骤，教模型”怎么做”；Knowledge 注入的是”资料”——一段事实、一份文档，告诉模型”是什么”</strong>。</p></section>
<section><h2>二、Knowledge 与上下文、与 Skill reference 的关系<a href="#二knowledge-与上下文与-skill-reference-的关系"><span>#</span></a></h2><section><h3>是上下文吗<a href="#是上下文吗"><span>#</span></a></h3><p>不是。准确说法是：<strong>Knowledge 的存储态从不在 context 里，只有被检索命中、真正被拼进这次 API 调用 messages 数组的片段，才会动态进入 context</strong>。</p><p>一个企业知识库可能有几十万份文档、几个 GB 文本，永远不可能整体塞进任何模型的 context window。它更像一整座图书馆：图书馆本身不会搬进客厅，只有这次去借的那几本书，才会出现在手边。</p><div><div><div><div><span><p>检索命中的<br /><br />几个片段</p></span></div><div><span><p>拼进 messages</p></span></div><div><span></span></div><div><span><p>Knowledge Base<br /><br />向量库 / 文件系统<br /><br />体量可达 GB 级</p></span></div><div><span><p>Retriever<br /><br />算相似度、取 top-k</p></span></div><div><span><p>Context Window<br /><br />这次 API 调用能看到的全部</p></span></div><div><span><p>LLM</p></span></div>
</div><div><div><span><p>检索命中的<br /><br />几个片段</p></span></div><div><span><p>拼进 messages</p></span></div><div><span></span></div><div><span><p>Knowledge Base<br /><br />向量库 / 文件系统<br /><br />体量可达 GB 级</p></span></div><div><span><p>Retriever<br /><br />算相似度、取 top-k</p></span></div><div><span><p>Context Window<br /><br />这次 API 调用能看到的全部</p></span></div><div><span><p>LLM</p></span></div>
</div></div></div><p>判定标准可以说得很直接：<strong>躺在向量数据库或文件系统里、没被检索到的，是 Knowledge（候选来源）；真正被查询命中、出现在这次 messages 数组里的，才是 context（当次内容）</strong>。</p></section><section><h3>是 Skill 的 reference 吗<a href="#是-skill-的-reference-吗"><span>#</span></a></h3><p>机制相似，但不是一回事。Skill 的 reference（比如 SKILL.md 里写”参见 template.docx”）是<strong>指令驱动、确定性、整份加载</strong>——只要 SOP 里写了要读这份文件，Agent 就会把它整份读进来，命中率 100%，不存在”读一半”的情况。Knowledge 检索是<strong>语义检索、概率性、只取 top-k 片段</strong>——命不命中取决于向量相似度打分，同一个知识库、同一份资料，换一种问法就可能查不到，也可能只捞出无关的半句话。</p>

<table><thead><tr><th>维度</th><th>Skill Reference</th><th>Knowledge 检索</th></tr></thead><tbody><tr><td>驱动方式</td><td>指令写死引用哪份文件</td><td>向量相似度打分</td></tr><tr><td>命中率</td><td>确定性，100%</td><td>概率性，top-k 近似</td></tr><tr><td>加载粒度</td><td>整份文件</td><td>切碎后的片段（chunk）</td></tr><tr><td>决定者</td><td>写 SOP 的人</td><td>检索算法在运行时决定</td></tr></tbody></table></section></section>
<section><h2>三、是否一开始加载 &amp; upload 文件算什么<a href="#三是否一开始加载--upload-文件算什么"><span>#</span></a></h2><section><h3>默认策略：惰性检索，不是启动全量加载<a href="#默认策略惰性检索不是启动全量加载"><span>#</span></a></h3><p>一个常见误解是：只要挂了知识库，模型启动的那一刻就把内容全读了一遍。事实上默认策略是<strong>惰性检索（lazy retrieval）</strong>——知识库平时安静地躺在向量数据库里，只有用户提问的那一刻，才会去检索、取出最相关的几段拼进 prompt。</p><p>原因很直接：<strong>窗口装不下，装得下也不划算</strong>。窗口装不下好理解，几十万字的知识库常态化超过任何模型的 context 上限。装得下也不划算，是因为即便用 prompt caching 把知识库整体缓存住，每次调用依然要为”读一遍缓存”的部分付一小笔钱、占一份窗口，知识库越大，这份固定成本就越贵。</p><p><strong>唯一的例外是知识库本身足够小的时候</strong>。Anthropic 在 <em>Introducing Contextual Retrieval</em> 这篇工程博客里给出了具体数字：<strong>如果知识库小于 20 万 token（约 500 页材料），可以直接把整个知识库放进 prompt，不需要 RAG</strong>，配合 prompt caching 后延迟能降低 2 倍以上、成本最多降 90%。只有当知识库继续增长、超过这个量级，才值得上更复杂的检索方案。这个”20 万 token”的分界线，第九节会看到它几乎是三家产品的共同默契。</p></section><section><h3>upload 文件算什么<a href="#upload-文件算什么"><span>#</span></a></h3><p>用户上传文件，只是灌入 Knowledge 的其中一种途径，实际落地方式分两种，性质完全不同：</p><p><strong>单次对话拖文件</strong>：等同于临时上下文，文件内容作为这一轮 user 消息的一部分直接进 context，会话结束（或开新对话）就失效，不会被任何机制持久化，下次再问模型”还记得那份文件吗”，回答一定是不记得，因为它从未被存进任何跨会话的地方。</p><p><strong>配置为 Knowledge Source</strong>：文件被写入某个持久化存储（Claude Projects 的 project knowledge、OpenAI 的 vector store、Gemini 的 File Search store），跨会话常驻，之后每次提问都可能被检索命中。</p></section></section>
<section><h2>四、聊天框 与 Project 中的 Knowledge<a href="#四聊天框-与-project-中的-knowledge"><span>#</span></a></h2><p>普通聊天框（比如不开 Projects 的一次性对话）当然”有知识内容”——这次对话里拖进来的文件，模型完全读得到、答得出。但它没有”持久知识库”：这份文件只活在这一次的 context 里，会话一关、窗口一超，内容就彻底消失，不会被任何向量库记录，下次开新对话等于从未上传过。</p><p>只有 Project（Claude Projects、ChatGPT Projects、自定义 GPT 的 knowledge files、Gemini 的 Gems / File Search）才提供<strong>跨会话持久、可复用的 Knowledge Base</strong>——文件上传一次，之后每次在这个 Project 里开新对话，都可能被重新检索到。</p><p>所以准确的措辞不是”普通聊天框没有知识”，而是**“普通聊天框没有持久化、可挂载的知识库”**——它有的只是一次性的长 context，会话结束即焚。</p></section>
<section><h2>五、Knowledge 如何与 LLM 关联 / LLM 怎么知道自己有知识<a href="#五knowledge-如何与-llm-关联--llm-怎么知道自己有知识"><span>#</span></a></h2><p>呼应 Token 那篇的核心结论——<strong>自然语言在 LLM 内部不存在，模型只处理数字</strong>——这里同样成立：Knowledge 与 LLM <strong>只有一条关联路径：知识内容变成 context 里的 token</strong>。不存在第二条路径能让 LLM 凭空”知道”自己有一个知识库，它不会读数据库的 schema，不会感知向量库里躺着多少份文件，它能看到的永远只是这一次 API 调用 messages 数组里已经拼好的文字。</p><p>这条唯一路径之上，衍生出两种截然不同的工作模式：</p><p><strong>模式一：传统 RAG</strong>。检索这件事完全发生在 LLM 外部，由应用层的 orchestrator 代劳——先做检索，再把结果拼进 prompt，LLM 从头到尾是被动接收方，它不知道、也不需要知道这段文字是”从知识库查来的”还是”用户自己打的”，更谈不上任何声明。</p><p><strong>模式二：Agentic RAG</strong>。知识库被包装成一个工具（比如 <code>search_knowledge_base</code>），连同其他工具一起，通过工具的 description 出现在这次调用的工具清单里。LLM 看到工具描述，自己判断”这个问题需不需要查知识库”，主动发起调用。这一模式下 LLM 是<strong>主动</strong>知道自己”有知识可查”的——它看到的是一份工具清单，跟看到 Skill 清单没有本质区别，这也是 Agentic RAG 与 Skill 高度趋同的原因。</p></section>
<section><h2>六、外部检索器的例子<a href="#六外部检索器的例子"><span>#</span></a></h2><p>一个具体例子：embedding 模型（OpenAI text-embedding、Voyage、Gemini embeddings 等）配合向量数据库（Azure AI Search、Pinecone、FAISS、Milvus 等）。</p><p>整个流程分离线、在线两段，<strong>离线阶段 LLM 完全不参与</strong>：</p><ol>
<li><strong>切块</strong>：把文档切成几百 token 一段的小块（OpenAI 的 file_search 工具默认切成 800 token、重叠 400 token）。</li>
<li><strong>向量化</strong>：用 embedding 模型把每个块转成一个高维向量。</li>
<li><strong>入库建索引</strong>：向量连同原文写入向量数据库，建好可供近似搜索的索引。</li>
</ol><p>运行阶段则是：</p><ol>
<li>用户提问，用同一个 embedding 模型把问题也转成向量；</li>
<li>在向量数据库里计算相似度，取 top-k 个最相关的块（OpenAI file_search 默认取 20 个块，Anthropic 在 Contextual Retrieval 的实验里也发现取 20 个块效果最好——两家不约而同选中同一个数字）；</li>
<li>把这几个块拼进 prompt；</li>
<li>交给 LLM 生成最终回答。</li>
</ol><div><div><div><div><span><p>运行时　·　每次提问都触发</p></span></div><div><span><p>离线预处理　·　LLM 不参与，只执行一次</p></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>提供索引</p></span></div><div><span><p>原始文档</p></span></div><div><span><p>切块<br /><br />chunking</p></span></div><div><span><p>Embedding 模型<br /><br />转成向量</p></span></div><div><span><p>向量数据库<br /><br />建索引</p></span></div><div><span><p>用户问题</p></span></div><div><span><p>Embedding 模型<br /><br />转成向量</p></span></div><div><span><p>计算相似度</p></span></div><div><span><p>取 top-k 个块</p></span></div><div><span><p>拼进 prompt</p></span></div><div><span><p>LLM 生成回答</p></span></div>
</div><div><div><span><p>运行时　·　每次提问都触发</p></span></div><div><span><p>离线预处理　·　LLM 不参与，只执行一次</p></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>提供索引</p></span></div><div><span><p>原始文档</p></span></div><div><span><p>切块<br /><br />chunking</p></span></div><div><span><p>Embedding 模型<br /><br />转成向量</p></span></div><div><span><p>向量数据库<br /><br />建索引</p></span></div><div><span><p>用户问题</p></span></div><div><span><p>Embedding 模型<br /><br />转成向量</p></span></div><div><span><p>计算相似度</p></span></div><div><span><p>取 top-k 个块</p></span></div><div><span><p>拼进 prompt</p></span></div><div><span><p>LLM 生成回答</p></span></div>
</div></div></div><p>核心结论是：<strong>检索器独立于 LLM 运行，只做”比较向量距离谁更近”的数学活</strong>，这一步是纯粹的线性代数与工程索引问题（常用 HNSW、IVF 等近似最近邻算法），跟”理解语言”没有任何关系，LLM 全程不参与这一步的计算。</p></section>
<section><h2>七、检索结果在 prompt 里的具体呈现<a href="#七检索结果在-prompt-里的具体呈现"><span>#</span></a></h2><p>呼应 Context 那篇提到的四种标准 role（system / user / assistant / tool）——<strong>Knowledge 检索结果没有专属的 role</strong>，最终必须伪装成这四种里的一种才能进入 context。实践中常见三种做法：</p><p><strong>做法 A：塞进 user 消息</strong>。最常见的传统 RAG 实现，把检索到的几段资料和用户原始问题拼在一起，包一层”以下是相关资料：……\n用户问题：……”，整个包装完的文本作为一条 user 消息发给模型。LLM 对此浑然不觉，它看到的只是一条比较长的 user 输入，无法分辨哪部分是用户写的、哪部分是检索器塞的。</p><p><strong>做法 B：塞进 system 消息</strong>。把检索结果当成背景设定放进 system prompt，常见于企业客服类场景——把命中的产品手册片段写进 system，人设加资料一起定义这轮对话的背景。</p><p><strong>做法 C：以 tool 返回，前面配一个 tool_calls</strong>。这是 Agentic RAG 的标准做法——模型主动发起一次 tool_use 调用（比如调用 <code>search_knowledge_base</code>），检索器执行后把结果包成 tool_result 传回去。这里可以直接借用 Context 那篇提到的一个细节：<strong>tool_result 的 role 其实是 user</strong>，因为 Anthropic 的设计逻辑是工具执行器站在用户侧，把结果”递给”模型。也就是说，即便是最像 Skill 的 Agentic RAG，检索结果最终进入 context 时，依然要套上四种标准 role 之一——通常又是套上了 user。</p></section>
<section><h2>八、是否每轮都做向量比对<a href="#八是否每轮都做向量比对"><span>#</span></a></h2><p>默认是的，做法 A、B 这类无脑塞入的实现，每一轮提问都会重新触发一次完整的检索流程。但这不等于”每轮都要把整个知识库重新算一遍”，中间有几层工程上的修正：</p><p><strong>知识库的向量早就预存好了</strong>，第六节的离线阶段只做一次，之后每一轮只需要重新计算”这句提问”的 embedding，知识库那一侧的向量是现成的，不会被重复计算。</p><p><strong>检索靠索引近似搜索，不是逐一扫全库</strong>。向量数据库依赖 HNSW、IVF 这类近似最近邻算法，把毫秒级的响应时间和几乎线性的召回质量做了权衡，即便知识库有几十万条向量，一次查询通常也就是几毫秒到几十毫秒。</p><p><strong>真正的成本大头不在向量比对本身，而在每轮注入 context 的那几段资料 token</strong>——这与 Context 那篇的结论一致：Agent 系统里 tool_result 才是消耗大户，检索命中的几个 chunk 一旦拼进 prompt，就是实打实的输入 token，要按次付费、占用窗口，向量数据库那边的计算开销相比之下可以忽略不计。</p><p>有两个常见的优化方向：一是<strong>加一道门控判断</strong>，先用一个轻量分类器判断这轮提问要不要检索，不需要就跳过，省下一次检索调用；二是<strong>改成 Agentic 检索</strong>，把检索包装成工具，让模型自己判断要不要调，用不上就不调。多轮对话场景下还有一个绕不开的问题：<strong>用户这一轮的原始提问经常是”那它呢""再详细说说”这类指代不明的短查询</strong>，直接拿去做向量检索效果很差（语义信息不完整），因此需要先做 <strong>query rewriting</strong>——用 LLM 把带着历史上下文的提问改写成一句独立、完整的检索查询，再送去做向量比对。</p></section>
<section><h2>九、主流产品策略（ChatGPT / Claude / Gemini）<a href="#九主流产品策略chatgpt--claude--gemini"><span>#</span></a></h2><p>三家的共同核心策略高度一致：<strong>知识库小就走 long-context 全量塞入，知识库大就切换到 RAG</strong>，分界线大致在<strong>20 万 token</strong>附近，正是第三节提到的 Anthropic 那条经验值，三家的产品设计大致都在这条线附近做取舍。</p><p><strong>Claude</strong>：Projects 会在 project knowledge 接近 context window 上限时<strong>自动</strong>切换到 RAG 模式，官方说明这一步可将知识容量扩容至多 10 倍，且是双向可逆的——如果之后内容量又降回阈值以下，会自动切回 context 模式，全程不需要用户手动配置。在检索质量上，Anthropic 通过 <strong>Contextual Retrieval</strong>（Contextual Embeddings + Contextual BM25，再叠加 Cohere 重排序）把 top-20 chunk 检索失败率从 5.7% 降到 1.9%，相当于降低 67%。2026 年 3 月，Claude Opus 4.6 与 Sonnet 4.6 的 1M token 上下文窗口已按标准价格全量开放，进一步抬高了”直接塞 long context”这条路径能覆盖的场景。</p><p><strong>OpenAI</strong>：策略更偏”按文件类型分流”——ChatGPT 对文本类文件（PDF、Word、PPT）走文本抽取 + 检索，对表格类文件（CSV、Excel）交给 Code Interpreter 用 Python 直接跑分析，对图片走 Vision 描述，三条路径互不相同；开发者侧的 file_search 工具默认按 800 token 切块、重叠 400 token、取 top-20 chunk 拼进 prompt。GPT-5.5 在 2026 年 4 月把 API 端上下文窗口做到了 100 万 token，是 OpenAI 第一个达到这一量级的模型。相比之下，普通 ChatGPT Projects 里”自动检索”这一层目前还不够成熟——开发者社区里能看到”把 Project 级检索能力搬到 ChatGPT 里”的功能请求帖，说明这块拼图眼下还在补齐中。</p><p><strong>Gemini</strong>：押注的方向是<strong>超大窗口 + Context Caching</strong>——当前的 Gemini 3.1 Pro 输入上限为 1,048,576 token；Google 官方的 long-context 文档明确表达了这层立场：更小窗口的模型需要”滑动窗口丢弃旧消息、摘要压缩、RAG 检索”这类补救手段，而 Gemini 的超大窗口鼓励一种更直接的做法——<strong>把相关信息一次性全部放进去</strong>。与此同时，implicit context caching 在 Gemini 2.5 及之后的模型上默认自动生效（最低缓存门槛 2,048–4,096 token 不等），命中缓存部分的输入输出成本可降至标准价格的四分之一左右，完全不需要开发者写代码开启。File Search 这个托管 RAG 工具则更像一层面向开发者的 API 级基础设施——自动完成切块、向量化、建索引，2026 年新增了多模态检索能力，但定位始终不是面向普通用户、开箱即用的 Project 知识库产品。</p><p>三家共同的演化方向也很清楚：<strong>检索正在从”被动拼接”走向”模型主动调用的工具”</strong>——Claude 的 project knowledge search tool、OpenAI 的 file_search、Gemini 的 File Search tool，本质上都是把第五节的”模式二：Agentic RAG”做成了标准配置，这条路线也是三家都在收敛的共同答案。</p>

<table><thead><tr><th>产品</th><th>切换机制</th><th>阈值 / 触发方式</th><th>特色技术</th></tr></thead><tbody><tr><td>Claude Projects</td><td>自动、双向可逆</td><td>接近 context window 上限</td><td>Contextual Retrieval（降失败率 67%）</td></tr><tr><td>ChatGPT / GPT API</td><td>按文件类型分流</td><td>文本 / 表格 / 图片走不同路径</td><td>file_search 默认 800 token 切块、top-20</td></tr><tr><td>Gemini</td><td>大窗口优先 + 托管 RAG 兜底</td><td>1M token 窗口内直接塞入</td><td>Implicit Context Caching（默认开启）</td></tr></tbody></table></section>
<section><h2>十、由该机制衍生的常见现象<a href="#十由该机制衍生的常见现象"><span>#</span></a></h2>

<table><thead><tr><th>现象</th><th>原因</th></tr></thead><tbody><tr><td>上传的文件这次对话记得住，换个新对话就”失忆”</td><td>文件走的是临时上下文路径，没有配置成持久 Knowledge Source</td></tr><tr><td>同一份知识库，换一种问法就查不到关键信息</td><td>检索是语义相似度打分，概率性命中，不是确定性引用</td></tr><tr><td>Project 里文件越堆越多，回答反而变慢或变糙</td><td>项目知识接近阈值触发 RAG，检索质量取决于切块与召回，不再是全量阅读</td></tr><tr><td>追问”那它呢”时答案文不对题</td><td>原始短查询语义不完整，未做 query rewriting 直接去检索，命中片段跑偏</td></tr><tr><td>同样的知识库，Claude 和 ChatGPT 表现不一样</td><td>底层检索机制不同（Contextual Retrieval + 重排序 vs 默认切块检索）</td></tr><tr><td>模型说”我不知道你上传的文件里有什么”</td><td>该内容尚未被检索命中，没有进入这次的 context，模型无法感知未被拼入的信息</td></tr><tr><td>知识库很小的时候，检索效果反而没有”全塞进去”好</td><td>知识库小于约 20 万 token 时，直接长 context 优于切块检索，切块本身会丢失片段间的关联</td></tr></tbody></table></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/prompt-to-skill/</id>
      <title type="text">From Prompt to Skill：Agent 技能机制与上下文调度</title>
      <published>2026-08-31T00:00:00.000Z</published>
      <updated>2026-08-31T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/prompt-to-skill/"/>
      <summary type="text">详解 Agent Skill 的起源、目录规范、渐进式披露机制，以及从传统 Prompt 到可执行 Skill 的工程演进</summary>
      <content type="html"><![CDATA[<section><h2>1. 问题从哪里开始<a href="#1-问题从哪里开始"><span>#</span></a></h2><p>理解 Agent Skill(智能体技能)最常见的误区,是把它想象成”给模型装了个插件”或”让模型学会了新本事”。这两种直觉都不准确。</p><p>真正需要先接受的前提是:<strong>Skill 从头到尾没有触及大语言模型(LLM)本身</strong>——它不修改任何一个模型权重,不改变模型的推理过程,也不是模型”内部”的一部分。一个 Skill 最终对模型产生影响的唯一途径,和一段普通提示词(prompt)完全一样:<strong>变成 token,进入上下文窗口(context window),被同一次前向推理(forward pass)读取。</strong></p><p>所以要真正搞懂 Skill 是什么,不能停留在”它是一种能力封装”这种模糊说法：</p><ul>
<li>它到底以什么<strong>形式</strong>存在于磁盘上?</li>
<li>它以什么<strong>角色(role)</strong>、在什么<strong>时机</strong>进入上下文窗口?</li>
<li>它和普通 prompt、和 system prompt、和 tool call、和 MCP 到底是什么关系?</li>
</ul><p>我们可以通过这几个问题来搞懂skill。</p><p>本质上,<strong>Skill 是一套围绕”上下文窗口”这一稀缺资源做加载调度的机制</strong>,而不是一样神秘的新东西。</p><hr /></section>
<section><h2>2. Skill 的起源&lt;谁提出的&gt;,为了解决什么<a href="#2-skill-的起源为了解决什么"><span>#</span></a></h2><p><strong>Agent Skills 这一概念由 Anthropic 在 2025 年 10 月正式提出</strong>,并很快演变成一个跨平台的开放格式——微软 Copilot Studio、GitHub Copilot、Cursor、Gemini CLI 等生态随后都采用或兼容了这套思路。</p><p>它要解决的,是<strong>纯 prompt 工程在规模化时的三个结构性痛点</strong>:</p>

<table><thead><tr><th>纯 prompt 的痛点</th><th>具体表现</th><th>Skill 的对策</th></tr></thead><tbody><tr><td><strong>不可复用</strong></td><td>每次做同类任务都要重新粘贴一大段指令</td><td>把流程写一次,存成文件,到处调用</td></tr><tr><td><strong>占满上下文</strong></td><td>想让模型”随时会做” N 种任务,就得把 N 套完整指令全塞进 system prompt,窗口被撑爆</td><td>平时只暴露一行简短描述,用到才展开</td></tr><tr><td><strong>要人手动触发</strong></td><td>用户得自己判断”这次该用哪套指令”</td><td>由编排器(orchestrator)根据描述自动选择</td></tr></tbody></table><p>简单来说:<strong>Skill 是把 prompt 工程”产品化”了</strong>——加上了持久化、按需加载、自动路由,以及(关键的)可选的代码执行能力。</p><hr /></section>
<section><h2>3. Skill 到底是什么&lt;定义与形式&gt;<a href="#3-skill-到底是什么"><span>#</span></a></h2><p>从底层来讲,<strong>一个 Skill 就是磁盘上的一个文件夹</strong>。文件夹里<strong>必须有一个 <code>SKILL.md</code> 文件</strong>,可选地附带脚本、参考文档、模板等资源。</p><p>一个完整 Skill 在磁盘上长这样:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>pdf-skill/                    ← 整个 Skill 就是一个文件夹</span></div></div><div><div><div>2</div></div><div><span>├── SKILL.md                  ← 核心:元数据(标题)+ 正文(指令)</span></div></div><div><div><div>3</div></div><div><span>├── scripts/                  ← 可执行脚本</span></div></div><div><div><div>4</div></div><div><span>│   ├── fill_form.py</span></div></div><div><div><div>5</div></div><div><span>│   └── merge_pdf.py</span></div></div><div><div><div>6</div></div><div><span>├── references/               ← 参考文档</span></div></div><div><div><div>7</div></div><div><span>│   └── pdf_spec_notes.md</span></div></div><div><div><div>8</div></div><div><span>└── assets/                   ← 模板 / 静态素材</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>└── letterhead_template.pdf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>SKILL.md</code> 本身内部又分两部分:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>name</span><span>: </span><span>pdf-form-filler</span></div></div><div><div><div>3</div></div><div><span>description</span><span>: </span><span>当用户需要填写或处理 PDF 表单时使用     ← 元数据(标题)</span></div></div><div><div><div>4</div></div><div><span>---</span></div></div><div><div><div>5</div></div><div><span># 填写 PDF 表单                                      ← 正文(指令)1. 读取用户提供的字段数据</span></div></div><div><div><div>6</div></div><div><span><span>2.</span><span> 调用 scripts/fill_form.py 完成填充</span></span></div></div><div><div><div>7</div></div><div><span><span>3.</span><span> 细节规格见 references/pdf_spec_notes.md</span></span></div></div><div><div><div>8</div></div><div><span>...</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>它把”某一类任务该怎么做”的<strong>流程性知识</strong>固化下来,让一个通用模型在需要时表现得像某个领域的专家。</p><hr /></section>
<section><h2>4. 三层结构&lt;渐进式披露&gt;(Progressive Disclosure)<a href="#4-三层结构progressive-disclosure"><span>#</span></a></h2><p>Skill 最核心的设计,是把内容分成<strong>三层</strong>,按需逐层加载。这套机制叫<strong>渐进式披露</strong>,目的只有一个:<strong>省上下文窗口</strong>。</p>

<table><thead><tr><th>层级</th><th>内容</th><th>加载时机</th><th>Token 成本</th></tr></thead><tbody><tr><td><strong>L1 元数据</strong></td><td>frontmatter 里的 <code>name</code> + <code>description</code>(约几十 token)</td><td><strong>启动时常驻</strong>,让模型”知道有这本书”</td><td>极小,一直付</td></tr><tr><td><strong>L2 正文</strong></td><td><code>SKILL.md</code> 的完整 Markdown 指令</td><td><strong>仅当任务匹配时</strong>才注入</td><td>触发才付</td></tr><tr><td><strong>L3 资源</strong></td><td><code>scripts/</code> <code>references/</code> <code>assets/</code> 里的文件</td><td>按需读取或执行</td><td>见第 9、11 节</td></tr></tbody></table><p>用一个类比贯穿理解:</p><ul>
<li><strong>L1 元数据</strong> = 一本书的<strong>书名 / 目录里的一行标题</strong>——“第 7 章&lt;如何填&gt; PDF 表单”。</li>
<li><strong>L2 正文</strong> = 第 7 章的<strong>完整内容</strong>。平时不翻,真要做这件事时才翻到那一页读进来。</li>
<li><strong>L3 资源</strong> = 附录里的<strong>计算器和详细规格表</strong>。你用计算器算,但不需要把它的电路图背下来。</li>
</ul><p>正因如此,有 50 个 Skill,平时只占 50 行简短描述的成本(几百 token),而不是 50 套完整指令。<strong>模型在有限窗口里能”认识”上百种能力,却不必时刻背着它们的全文。</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>flowchart TD</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>A[会话启动] --&gt; B[L1: 50 行 description 常驻 system]</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>B --&gt; C{用户提出需求}</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>C --&gt;|匹配到某 Skill| D[L2: 该 Skill 正文动态注入]</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>D --&gt; E{正文里引用了资源?}</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>E --&gt;|要执行脚本| F[L3 scripts: 窗口外运行, 只回填结果]</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>E --&gt;|要查参考| G[L3 references: 按需读取部分进窗口]</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>E --&gt;|不需要| H[直接完成任务]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section>
<section><h2>5. 例子&lt;生成规范&gt; Excel<a href="#5-例子-excel"><span>#</span></a></h2><p>用同一个任务对比”纯 prompt”和”Skill”,能立刻看清差别。任务是:<strong>把一批数据做成一张格式规范的 Excel 表</strong>。</p><p><strong>方案 A — 纯 Prompt(每次手敲):</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>请帮我生成 Excel。要求:</span></div></div><div><div><div>2</div></div><div><span>- 表头加粗、底色深蓝、白字</span></div></div><div><div><div>3</div></div><div><span>- 冻结首行,数字列右对齐保留 2 位小数</span></div></div><div><div><div>4</div></div><div><span>- 金额列用千分位,列宽自适应</span></div></div><div><div><div>5</div></div><div><span>- 用 openpyxl 输出到 output.xlsx</span></div></div><div><div><div>6</div></div><div><span>数据如下:...</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>下次再做同类任务,这段又得从头贴一遍。</p><p><strong>方案 B — Skill(建一次,长期复用):</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>xlsx-skill/</span></div></div><div><div><div>2</div></div><div><span>├── SKILL.md          # name + description + 上面那套格式规范</span></div></div><div><div><div>3</div></div><div><span>└── scripts/</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>└── format_table.py   # 真正干活的代码</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>之后你只需说”把这批数据做成 Excel”,模型读到 L1 描述判断匹配,把 L2 正文拉进来,再调用 <code>format_table.py</code> 完成——那段格式规范再也不用手敲。</p><hr /></section>
<section><h2>6. Skill vs Prompt&lt;本质相同&gt;,定位不同<a href="#6-skill-vs-prompt定位不同"><span>#</span></a></h2><p><strong>两者本质上都是”外部输入”&lt;都不改变模型权重&gt;,都以 token 进入上下文,由同一次推理处理。</strong> 从这个意义上说,它们和微调(fine-tuning)、RLHF 这种真正改动参数的手段有本质区别——后者才”触及根本”。</p><p>但在”外部提示”这个大类里,两者定位差别很清楚:</p>

<table><thead><tr><th>维度</th><th>Prompt</th><th>Skill</th></tr></thead><tbody><tr><td>形态</td><td>一段即时文本</td><td>一个文件夹(SKILL.md + 可选资源)</td></tr><tr><td>生命周期</td><td>一次性,用完即弃</td><td>持久化,跨会话 / 跨项目复用</td></tr><tr><td>加载方式</td><td>写多少就全量进窗口</td><td>渐进式披露,平时只占一行描述</td></tr><tr><td>触发者</td><td>人手动输入</td><td>模型 / 编排器<strong>自主判断</strong>何时调用</td></tr><tr><td>能力边界</td><td>纯文本,不能自带可执行代码</td><td>L3 可附带脚本,能被执行</td></tr><tr><td>类比</td><td>口头临时交代一件事</td><td>一本写好、需要时才翻的操作手册</td></tr></tbody></table><p><strong>关键区别不在”是否触及模型”,而在”复用性 + 加载机制 + 谁来触发 + 能否外挂执行”。</strong> Skill 可以粗略理解成”被规范化、模块化、按需加载的 prompt 仓库”,外加一层纯 prompt 做不到的可执行能力。</p><hr /></section>
<section><h2>7. Skill 是不是 system prompt?<a href="#7-skill-是不是-system-prompt"><span>#</span></a></h2><p>既然skill是以prompt的形式出现在上下文，那么它的role是什么，是system prompt吗？</p><p>答案是:<strong>不完全等于,但有交集,而且必须精确措辞。</strong></p><p>先厘清 “system prompt” 到底指什么。在一次推理里,送进上下文窗口的文本按**角色(role)**分层:</p>

<table><thead><tr><th>角色</th><th>内容</th><th>特点</th></tr></thead><tbody><tr><td><strong>System</strong></td><td>人设、全局规则、可用工具 / 技能清单</td><td>常驻、权威最高、用户一般看不到</td></tr><tr><td><strong>User</strong></td><td>用户当前的话</td><td>逐轮变化</td></tr><tr><td><strong>Assistant</strong></td><td>模型自己的回复</td><td>逐轮生成</td></tr></tbody></table><p>所谓 system prompt,就是 <strong>System 角色那一段</strong>,而它的定义里隐含了”静态常驻”。</p><p>Skill 的两层内容,落点不同:</p><ul>
<li><strong>L1 元数据(那行描述)</strong> → 确实被塞进 <strong>System 区</strong>并常驻,让模型一直知道有哪些技能可选。<strong>这部分算 system prompt 的一部分。</strong></li>
<li><strong>L2 正文</strong> → 触发后<strong>动态注入</strong>。它以 System 级的权威进入,但它是”会进出的”,不是一开始就钉在那儿的固定 prompt。</li>
</ul><p>所以严谨的表述是:</p><blockquote><p><strong>L2 正文是”动态注入的 system 级指令片段”,而不是”一段动态的 system prompt”。</strong></p></blockquote><p>而且要记住:<strong>Skill ≠ 只有正文</strong>。它还有 L3 那层——<strong>那是窗口外的可执行代码,根本不是 prompt</strong>。所以”本质上是一种 prompt”这句话只覆盖了 L1 + L2。</p><hr /></section>
<section><h2>8. 动态注入 vs 静态注入&lt;区别到底在哪&gt;<a href="#8-动态注入-vs-静态注入"><span>#</span></a></h2><p>这是理解 Skill 机制的核心:</p><p><strong>对模型的单次前向推理来说,“一开始注入”和”运行时注入”没有任何区别。</strong> 模型只看它这一刻窗口里有什么 token,token <strong>不带时间戳</strong>,模型无从分辨哪段是开机就有、哪段是刚才才塞的。</p><p>那区别在哪?<strong>在整场多轮对话里,这段文本存在多久、占用多少、由谁决定。</strong></p>

<table><thead><tr><th></th><th>一开始注入(静态)</th><th>运行时注入(动态)</th></tr></thead><tbody><tr><td>进入时机</td><td>会话启动,第 0 轮就在</td><td>某轮触发条件满足才加入</td></tr><tr><td>存在时长</td><td>全程常驻,每一轮都在</td><td>用完可撤走,只在相关轮次占用</td></tr><tr><td>谁决定</td><td>系统预先写死</td><td>编排器根据当前需要临时决定</td></tr><tr><td>Token 成本</td><td>每一轮都重复付这份钱</td><td>只在需要的轮次付</td></tr></tbody></table><p>一个推演最能说明问题。假设有 50 个 Skill、对话进行 10 轮:</p><ul>
<li><strong>若全部静态注入</strong>&lt;每一轮窗口都背着&gt; 50 套完整正文(比如 5 万 token),被重复喂 10 次,而大部分这次根本用不上——纯浪费,上下文窗口很快撑满。</li>
<li><strong>若动态注入</strong>&lt;任何一轮窗口里只有&gt;”50 行索引 + 当前用得上的那 1 套正文”,省下 90%+ 的空间。</li>
</ul><p><strong>动态注入最大的价值是”可逆、可调度”:</strong></p><p>系统能用有限窗口支撑海量能力——模型平时只背一份薄目录,真要用哪一章,编排器现场翻开塞给它,用完合上。</p><hr /></section>
<section><h2>9. L3 资源&lt;不进窗口&gt;,怎么执行?<a href="#9-l3-资源怎么执行"><span>#</span></a></h2><p>这里要破除第二个误区:<strong>“进上下文”和”被执行”是两条完全独立的路径。</strong> 上下文窗口是给模型”读”的;执行是在模型之外的机器上”跑”的。</p><p><strong>模型本身不运行任何代码。</strong> LLM 是个文本预测器,只会输出 token。真正干活的是它旁边的<strong>运行环境(runtime / sandbox / 工具执行器)</strong>。流程是:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>① 模型在 L2 正文里读到:"调用 scripts/format_table.py 处理数据"</span></div></div><div><div><div>2</div></div><div><span>② 模型据此输出一个动作指令 token:</span></div></div><div><div><div>3</div></div><div><span><span>   </span></span><span>{ "tool": "bash", "command": "python scripts/format_table.py data.csv" }</span></div></div><div><div><div>4</div></div><div><span>③ 外部执行器收到 → 在沙箱里真正运行那个 .py 文件</span></div></div><div><div><div>5</div></div><div><span>④ 脚本跑完,把【结果】(成功/报错/输出值)作为文本回填进上下文窗口</span></div></div><div><div><div>6</div></div><div><span>⑤ 模型读到结果,继续下一步</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>所以进出上下文的到底是什么,要分清:</p>

<table><thead><tr><th>东西</th><th>进上下文吗</th><th>说明</th><th></th></tr></thead><tbody><tr><td>脚本的<strong>文件名 / 调用指令</strong></td><td>✅ 进</td><td>模型需要知道”有这工具、怎么调”</td><td></td></tr><tr><td>脚本的<strong>源代码内容</strong></td><td>❌ 不进</td><td>那几百行代码模型不用读</td><td></td></tr><tr><td>脚本的<strong>运行结果</strong></td><td>✅ 进</td><td>成功 / 失败 / 输出值,回填给模型看</td><td></td></tr></tbody></table><section><h3>bash 与 MCP tool&lt;两种执行路径&gt;<a href="#bash-与-mcp-tool"><span>#</span></a></h3><p>L3 的”让机器跑”本质就是<strong>工具调用(tool calling)</strong>,而 bash 和 MCP tool 是它下面的两种实现路径,不是二选一的对立关系。</p>

<table><thead><tr><th></th><th>Bash / 代码执行工具</th><th>MCP tool</th></tr></thead><tbody><tr><td>本质</td><td>授予模型一个”执行 shell 命令”的通用工具</td><td>授予模型一批”预定义好的具体工具”</td></tr><tr><td>粒度</td><td>粗、万能——一个 bash 能干任何事</td><td>细、专用——每个 tool 一个明确 schema</td></tr><tr><td>跑在哪</td><td>Agent 自带的代码沙箱</td><td>外部 MCP server 进程里</td></tr><tr><td>典型场景</td><td><strong>Skill 自带脚本</strong>、临时计算、文件操作</td><td>连数据库、调外部 API、访问企业系统</td></tr></tbody></table><p>分工大致是:</p><ul>
<li><strong>Skill 的 L3 脚本 → 走 bash / 代码执行</strong>&lt;处理&gt;”技能包自带、本地就能算的活”。Anthropic 官方的 Agent Skills 设计里,L3 资源就是靠代码执行工具跑的,<strong>不依赖 MCP</strong>。</li>
<li><strong>MCP tool → 走 MCP 协议</strong>&lt;处理&gt;”要连出去的活”。</li>
</ul><p>而且两者可<strong>嵌套</strong>&lt;一个&gt; Skill 的 L2 正文完全可以写”第 2 步&lt;调&gt; MCP 的 <code>query_db</code> 取数;第 3 步&lt;用本地脚本&gt; <code>format.py</code> 排版”。它们都只是 L2 指令层可调度的”执行手段”。</p></section><section><h3>bash 跑在哪台机器上<a href="#bash-跑在哪台机器上"><span>#</span></a></h3><p><strong>执行环境由”承载这个 Agent 的宿主”提供,而不是模型自带。</strong></p>

<table><thead><tr><th>产品形态</th><th>bash / 代码跑在哪</th><th>环境性质</th></tr></thead><tbody><tr><td><strong>云端 Agent 服务</strong></td><td>服务商后端起的一次性容器 / 微型 VM</td><td>云端沙箱,任务结束即销毁</td></tr><tr><td><strong>Claude Desktop 客户端</strong></td><td><strong>自身不带通用沙箱</strong>,靠外挂 MCP server</td><td>执行落到 server 所在处(可能是你本机)</td></tr><tr><td><strong>Codex CLI / Claude Code</strong></td><td>直接跑在<strong>你本机的 shell</strong></td><td>你的真实电脑,有真实文件访问权</td></tr><tr><td><strong>IDE 插件(Copilot / Cursor)</strong></td><td>通常在你本地工作区执行</td><td>你的开发机环境</td></tr></tbody></table><hr /></section></section>
<section><h2>10. role 的定义权与生效层级<a href="#10-role-的定义权与生效层级"><span>#</span></a></h2><p>一个更底层的问题&lt;注入进上下文的那段东西&gt;,role 到底是谁定的、在哪一层生效?这要拆成两个不同的问题。</p><section><h3>role 的”格式 / 字段” —— 定义权在 API 协议层<a href="#role-的格式--字段--定义权在-api-协议层"><span>#</span></a></h3><p><code>role: "system" / "user" / "assistant" / "tool"</code> 这套<strong>词汇表</strong>,由<strong>模型提供商的 API 规范</strong>定义。你(调用方)只能从它允许的 role 里挑,不能自己发明一个 <code>role: "boss"</code> ,API 会报错。所以”有哪些 role 可选”的定义权在<strong>接口层</strong>。</p></section><section><h3>role 的”效力 / 权威” —— 影响在模型端(训练里)<a href="#role-的效力--权威--影响在模型端训练里"><span>#</span></a></h3><p>为什么 system 比 user 权威?这个高低次序是谁赋予的?</p><p>答案是:<strong>在模型端,通过训练固化的。</strong></p><p>关键在于理解:<strong>对底层 Transformer 来说,输入其实是一整条被”拼平”的 token 序列,role 不是独立信道,而是被编码成特殊标记塞进序列里的:</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;|system|&gt; 你要遵守...  &lt;|end|&gt;</span></div></div><div><div><div>2</div></div><div><span>&lt;|user|&gt;   帮我做...    &lt;|end|&gt;</span></div></div><div><div><div>3</div></div><div><span>&lt;|assistant|&gt; ...</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>那些 <code>&lt;|system|&gt;</code> <code>&lt;|user|&gt;</code> 是<strong>特殊 token / 分隔标记</strong>。模型之所以”知道” system 那段更权威,不是因为字段名有魔力,而是在**训练阶段(instruction tuning + RLHF)**被喂了海量样本,反复学到:“当 system 段与 user 段冲突时,优先服从 system。”</p>

<table><thead><tr><th>层面</th><th>定义权在哪</th></tr></thead><tbody><tr><td>role 有哪些、字段叫什么、格式</td><td><strong>API 协议层</strong></td></tr><tr><td>role 之间的<strong>权威高低、谁压谁</strong></td><td><strong>模型端</strong>,由训练固化</td></tr><tr><td>把 role 转成模型能读的形式(套 chat template、加特殊 token)</td><td>中间的 serving 层</td></tr></tbody></table><p>拿一个<strong>没经过对齐训练的裸 base model</strong>,给它标 <code>role: system</code>,它根本不会因此更服从——因为它没被训练过”要尊重 system”。可见 role 的效力不在字段本身,<strong>而在模型学没学过</strong>。</p></section><section><h3>那 Skill 正文注入时是什么 role<a href="#那-skill-正文注入时是什么-role"><span>#</span></a></h3><p><strong>这是实现相关的</strong>,但有一点确定&lt;它&gt;<strong>绝不会是 <code>user</code></strong>(否则会被后续 user 输入覆盖,且角色语义错乱),一定在”权威侧”。主流实现有几种:</p>

<table><thead><tr><th>注入方式</th><th>具体 role</th><th>场景</th></tr></thead><tbody><tr><td>合并 / 追加进 system</td><td><code>system</code></td><td>直接把正文拼进或作为额外一条 system message</td></tr><tr><td>通过”读 skill 文件”工具拿到</td><td><code>tool</code> / <code>function</code></td><td><strong>Anthropic 式 Agent Skills 常接近这种</strong>,复用读文件管线</td></tr><tr><td>developer 分层体系</td><td><code>developer</code></td><td>部分新体系用它承载”应用级指令”,介于 system 与 user 之间</td></tr></tbody></table><p>所以:<strong>Skill 正文以 “system 级的权威” 进入上下文永远成立;但它在消息数组里挂的字面 role,取决于产品是”直接当 system 拼进去”还是”当作一次工具读取的返回”。</strong></p><hr /></section></section>
<section><h2>11. L3 的 reference 如何参与上下文<a href="#11-l3-的-reference-如何参与上下文"><span>#</span></a></h2><p>L3 内部还要再分”读”和”跑”两种命运——第 9 节讲的是”跑”(脚本),这里讲”读”(参考资料)。</p><p><strong>核心区别 通常不是被系统被动”直接加载”,而是模型主动去”读”的。</strong></p>

<table><thead><tr><th></th><th>L2 正文</th><th>L3 reference</th></tr></thead><tbody><tr><td>进场方式</td><td>Skill 一触发,系统<strong>主动注入</strong></td><td>模型读了 L2 后,<strong>自己决定</strong>要不要读</td></tr><tr><td>主动权</td><td>编排器 / 系统</td><td><strong>模型自己</strong></td></tr><tr><td>类比</td><td>翻开书直接看到第 7 章开头</td><td>第 7 章写”详见附录 B”,模型再翻附录 B</td></tr></tbody></table><p>具体流程——它走的是和 L3 脚本执行<strong>一模一样的工具调用管线</strong>,只不过脚本是”跑”、reference 是”读”:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>① 模型读到 L2 正文:"详细规格见 references/spec.md"</span></div></div><div><div><div>2</div></div><div><span>② 模型判断:这次任务需要这个细节</span></div></div><div><div><div>3</div></div><div><span>③ 模型输出动作 → { "tool": "read_file", "path": "references/spec.md" }</span></div></div><div><div><div>4</div></div><div><span>④ 外部执行器读取该文件 → 把内容(或指定的某几段)作为【结果】回填</span></div></div><div><div><div>5</div></div><div><span>⑤ 这段文本进入上下文,role 通常是 tool,模型接着用</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>所以 <strong>reference 回填进上下文时,最典型的 role 是 <code>tool</code>(工具返回结果)</strong>——因为它复用了现成的文件读取管线,和 L3 脚本共用一套机制。同样,这也是实现相关的&lt;少数实现会直接把内容拼进&gt; system 上下文,role 就成了 <code>system</code>。</p><p>reference 常常<strong>不是全量加载</strong>。它的价值恰恰在于可以<strong>只读需要的片段</strong>——带 offset 的部分读取,或先读目录 / 摘要再决定深入哪段。这就是**“更深一层的渐进式披露”** → L2 渐进过一次,reference 内部还能再渐进一次,尽量少占窗口。</p><hr /></section>
<section><h2>12. 核心结论<a href="#12-核心结论"><span>#</span></a></h2><ol>
<li>
<p><strong>Skill 从头到尾没有触及 LLM 本身。</strong> 它不改权重、不改推理,最终只是以 token 进入上下文窗口,和普通 prompt 走同一条路。它与微调 / RLHF 有本质区别。</p>
</li>
<li>
<p><strong>Skill 由 Anthropic 于 2025 年 10 月提出,现已成为跨平台开放格式。</strong> 它把 prompt 工程”产品化”,解决了纯 prompt 的三大痛点&lt;不可复用&gt;、占满上下文、要人手动触发。</p>
</li>
<li>
<p><strong>一个 Skill 就是一个文件夹</strong>,核心是 <code>SKILL.md</code>,内容分三层 元数据(常驻的”书名”)、L2 正文(动态注入的”章节内容”)、L3 资源(窗口外的脚本 / 参考 / 素材)。</p>
</li>
<li>
<p><strong>渐进式披露是它的灵魂。</strong> 平时只暴露 L1 的简短描述,匹配到任务才注入 L2;省的是上下文窗口这一稀缺资源的调度效率,而非模型的理解力。</p>
</li>
<li>
<p><strong>“动态注入”与”静态注入”对模型单次推理无区别</strong>(token 不带时间戳),区别在多轮对话中”存在多久、占多少、谁调度”——静态是纹身,动态是便利贴。</p>
</li>
<li>
<p><strong>L1 + L2 本质是”动态加载的 system 级提示”;L3 不是提示,是窗口外的可执行资源。</strong> L3 内部又分两种命运&lt;脚本&gt;”给机器跑”(bash 或 MCP,不进窗口,只回填结果),参考资料”给模型读”(按需读片段进窗口,role 通常是 tool)。</p>
</li>
<li>
<p><strong>role 的词汇表由 API 定义,role 的权力由训练在模型端刻死。</strong> Skill 正文以 system 级权威进入上下文永远成立,但其字面 role(system / tool / developer)取决于具体产品实现,唯一确定的是它绝不是 user。</p>
</li>
</ol><blockquote><p>Skill 不是一样神秘的新东西,而是一套围绕上下文窗口做加载调度的机制——用一个静态常驻的”书名”(L1)在 system 里挂号,用到时把”正文”(L2)以 system 级权威动态注入,必要时再指挥窗口外的脚本(L3)去干活。读的归读,跑的归跑,谁都不挤占本就稀缺的上下文窗口。</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/how-token-works/</id>
      <title type="text">从 Token 到向量：LLM 的输入输出机制</title>
      <published>2026-08-28T00:00:00.000Z</published>
      <updated>2026-08-28T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/how-token-works/"/>
      <summary type="text">解析自然语言向模型数字转化的全流程：分词器（Tokenizer）训练与编码机制、BPE 算法原理及 Token 经济学</summary>
      <content type="html"><![CDATA[<section><h2>一、问题的起点<a href="#一问题的起点"><span>#</span></a></h2><p>理解大语言模型（LLM）的处理机制，最常见的误区是将其类比为”会读字、会写字”的程序。事实并非如此——<strong>LLM 内部不存在”字符”或”文字”的概念</strong>，全部输入与输出在工程上均表现为数字，更准确地说，是高维空间中的向量。文字仅是人类世界与模型世界之间的一层转换接口，完成这层转换的组件称为 <strong>Tokenizer（分词器）</strong>。</p><p>要理解一段自然语言如何被 LLM 处理、为何不同输入的成本差异巨大、为何模型在某些字符级任务上（如统计 “strawberry” 中字母 r 的数量）表现异常，前提是搞清楚：<strong>一段自然语言如何被转换为模型实际处理的数字</strong>。</p><p>这一过程在工程上分为两个独立阶段。第一阶段是 <strong>分词器的训练</strong>，由模型厂商在模型发布前一次性完成，产物是一张固定的”切词规则表”。第二阶段是 <strong>编码</strong>，在每次 API 调用时执行，按照规则表将任意输入文本切成 token、再查表转换为整数 ID 交给模型。需要注意的区分：调用模型时分词器<strong>已经完成训练，规则表固定不变</strong>，编码阶段执行的仅是机械的”查表 + 合并”，不涉及任何学习行为。</p><div><div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>模型厂商<br /><br />海量训练语料</p></span></div><div><span><p>阶段一：训练分词器<br /><br />一次性</p></span></div><div><span><p>vocab.json<br /><br />merges.txt</p></span></div><div><span><p>阶段二：编码<br /><br />每次调用执行</p></span></div><div><span><p>用户输入文本</p></span></div><div><span><p>Token ID 序列</p></span></div><div><span><p>LLM</p></span></div>
</div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>模型厂商<br /><br />海量训练语料</p></span></div><div><span><p>阶段一：训练分词器<br /><br />一次性</p></span></div><div><span><p>vocab.json<br /><br />merges.txt</p></span></div><div><span><p>阶段二：编码<br /><br />每次调用执行</p></span></div><div><span><p>用户输入文本</p></span></div><div><span><p>Token ID 序列</p></span></div><div><span><p>LLM</p></span></div>
</div></div></div></section>
<section><h2>二、Token 的本质<a href="#二token-的本质"><span>#</span></a></h2><p>Token 是一种介于字母和单词之间的<strong>子词（subword）单位</strong>。一个具体 token 的形态，<strong>完全取决于该字符序列在训练语料中出现的频率</strong>。OpenAI 给出的经验值是英文场景下 1 token ≈ 4 个字符 ≈ ¾ 个英文单词，但该数值会因内容性质显著波动：纯英文常用词每个仅占 1 个 token，中文一个字往往占 1–2 个 token，乱码或罕见专有名词可能每个字符都要单独占用一个 token。</p><p>下表列出若干真实示例（可在 platform.openai.com/tokenizer 上验证）：</p>

<table><thead><tr><th>输入文本</th><th>切分结果</th><th>Token 数</th><th>说明</th></tr></thead><tbody><tr><td><code>" the"</code></td><td><code>[" the"]</code></td><td>1</td><td>英语最高频词之一，ID 极小（约 290）</td></tr><tr><td><code>"hello"</code></td><td><code>["hello"]</code></td><td>1</td><td>常见词，整体保留</td></tr><tr><td><code>"lowest"</code></td><td><code>["low", "est"]</code></td><td>2</td><td>词根 + 后缀，BPE 的典型行为</td></tr><tr><td><code>"tokenization"</code></td><td><code>["token", "ization"]</code></td><td>2</td><td>同上</td></tr><tr><td><code>"strawberry"</code></td><td><code>["str", "aw", "berry"]</code></td><td>3</td><td>拆分比预期更碎</td></tr><tr><td><code>"你好"</code></td><td><code>["你", "好"]</code></td><td>2–3</td><td>中文每字常占 1–2 token</td></tr><tr><td><code>"xq7zk!"</code></td><td><code>["x", "q", "7", "z", "k", "!"]</code></td><td>6</td><td>罕见组合退化到单字节</td></tr></tbody></table><p><strong>高频整词被合并成 1 个 token，中频词被拆为多个高频子词，罕见词或乱码退化为按单字节切分</strong>。这是 BPE 算法的核心特征。</p></section>
<section><h2>三、BPE 训练过程<a href="#三bpe-训练过程"><span>#</span></a></h2><p>BPE 全称为 <strong>Byte-Pair Encoding（字节对编码）</strong>，OpenAI、Anthropic、Meta Llama、Google Gemini 系列底层均使用该算法或其变体。训练过程可通过一段迷你语料逐步演示。</p><p>设训练语料仅包含四个词：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>low low low low low       (5 次)</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>lower lower               (2 次)</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>newest newest newest      (3 次)</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>widest widest widest      (3 次)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>第一步</strong>，所有词拆为单字符，词尾添加特殊符号 <code>&lt;/w&gt;</code> 标记词边界：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>"l o w &lt;/w&gt;"        × 5</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>"l o w e r &lt;/w&gt;"    × 2</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>"n e w e s t &lt;/w&gt;"  × 3</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>"w i d e s t &lt;/w&gt;"  × 3</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>此时词表包含 11 个 token：<code>{l, o, w, e, r, n, s, t, i, d, &lt;/w&gt;}</code>。</p><p><strong>第二步</strong>，扫描整个语料，统计”相邻字符对”的出现次数。例如 <code>l + o</code> 在 “low” 与 “lower” 中累计 5 + 2 = 7 次；<code>o + w</code> 同样为 7 次；<code>e + s</code> 在 “newest” 与 “widest” 中累计 6 次。<code>l + o</code> 与 <code>o + w</code> 并列最高频，任选其一（如 <code>l + o</code>）合并为新 token <code>lo</code> 加入词表，并记录合并规则：<code>l + o → lo</code>。</p><p><strong>第三步</strong>，重复扫描与合并。下一轮 <code>lo + w</code> 成为最高频对，合并为 <code>low</code>；再下一轮 <code>e + s</code> 最高频，合并为 <code>es</code>；再下一轮 <code>es + t</code> 合并为 <code>est</code>；继而 <code>est + &lt;/w&gt;</code> 合并为 <code>est&lt;/w&gt;</code>。整个过程持续进行，<strong>每轮合并当前最高频的字符对</strong>，直至词表达到预设大小。</p><div><div><div><div><span></span></div><div><span></span></div><div><span><p>否</p></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>是</p></span></div><div><span><p>初始化<br /><br />拆为单字符词表</p></span></div><div><span><p>扫描全语料<br /><br />统计相邻字符对频率</p></span></div><div><span><p>是否达到<br /><br />目标词表大小?</p></span></div><div><span><p>找出最高频字符对</p></span></div><div><span><p>合并为新 token<br /><br />加入词表</p></span></div><div><span><p>记录合并规则<br /><br />追加至 merges.txt</p></span></div><div><span><p>训练结束<br /><br />输出 vocab.json + merges.txt</p></span></div>
</div><div><div><span></span></div><div><span></span></div><div><span><p>否</p></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>是</p></span></div><div><span><p>初始化<br /><br />拆为单字符词表</p></span></div><div><span><p>扫描全语料<br /><br />统计相邻字符对频率</p></span></div><div><span><p>是否达到<br /><br />目标词表大小?</p></span></div><div><span><p>找出最高频字符对</p></span></div><div><span><p>合并为新 token<br /><br />加入词表</p></span></div><div><span><p>记录合并规则<br /><br />追加至 merges.txt</p></span></div><div><span><p>训练结束<br /><br />输出 vocab.json + merges.txt</p></span></div>
</div></div></div><p>OpenAI 训练 GPT-4o 时，合并至词表约 <strong>20 万 token</strong> 停止（对应的编码方案命名为 <code>o200k_base</code>）。训练完成后，产物<strong>仅有两个文件</strong>：</p><ol>
<li>
<p><strong>vocab.json</strong>：<code>{token 文本 → token ID}</code> 的映射表。</p>
</li>
<li>
<p><strong>merges.txt</strong>：数万至数十万条”x + y → xy”形式的合并规则，<strong>严格按照训练时的合并顺序排列</strong>。</p>
</li>
</ol><p>这两个文件合计通常仅几 MB，构成了 tiktoken 库的全部核心数据。<strong>训练完成后，两个文件永久固定，不再变更</strong>。</p></section>
<section><h2>四、BPE 编码过程<a href="#四bpe-编码过程"><span>#</span></a></h2><p>编码阶段以一个训练语料中<strong>未出现过</strong>的新词 <code>"lowest"</code> 为例：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Step 1: 拆为单字符          "l o w e s t &lt;/w&gt;"</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>Step 2: 按 merges.txt 顺序遍历规则，能合并则合并</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span><span>        </span></span><span>规则 #1  l + o → lo            →  "lo w e s t &lt;/w&gt;"</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span><span>        </span></span><span>规则 #2  lo + w → low          →  "low e s t &lt;/w&gt;"</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>规则 #3  e + s → es            →  "low es t &lt;/w&gt;"</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span><span>        </span></span><span>规则 #4  es + t → est          →  "low est &lt;/w&gt;"</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span><span>        </span></span><span>规则 #5  est + &lt;/w&gt; → est&lt;/w&gt;  →  "low est&lt;/w&gt;"</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>Step 3: 无更多可用规则，终止</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>最终结果: ["low", "est&lt;/w&gt;"]  →  token ID 例如 [10516, 478]</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>关键事实：<strong>训练语料中并未包含 “lowest” 一词</strong>，但分词器依靠已学到的 “low” 与 “est” 两个高频子词，仍能合理切分。这是 BPE 的核心价值——<strong>以有限的子词表覆盖近乎无限的词汇组合</strong>。</p><p>由此也可解释 Token ID 与频率的对应关系：BPE 训练按频率从高到低<strong>依次分配 ID</strong>，因此 ID 本身即反映频率高低：</p><div><div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>ID 0 ~ 255<br /><br />单字节兜底</p></span></div><div><span><p>ID 256 ~ 1000<br /><br />最高频组合<br /><br />(' the', 'ing', 'ed')</p></span></div><div><span><p>ID 1000 ~ 10000<br /><br />次高频组合</p></span></div><div><span><p>ID 10000 ~ 50000<br /><br />一般常见词</p></span></div><div><span><p>ID 50000 ~ 199999<br /><br />中低频词 / 长词<br /><br />其他语言 / 代码标识符</p></span></div>
</div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>ID 0 ~ 255<br /><br />单字节兜底</p></span></div><div><span><p>ID 256 ~ 1000<br /><br />最高频组合<br /><br />(' the', 'ing', 'ed')</p></span></div><div><span><p>ID 1000 ~ 10000<br /><br />次高频组合</p></span></div><div><span><p>ID 10000 ~ 50000<br /><br />一般常见词</p></span></div><div><span><p>ID 50000 ~ 199999<br /><br />中低频词 / 长词<br /><br />其他语言 / 代码标识符</p></span></div>
</div></div></div><p>Token ID 本质上是一张<strong>按频率排序的索引表</strong>：ID 越小代表 token 越高频、越常见；ID 越大代表越罕见、越”碎”。这也解释了为何 <code>"the the the"</code> 切出的 ID 都很小，而 <code>"xqzpfk"</code> 这类乱码切出的 ID 都在数万以上。</p></section>
<section><h2>五、不同厂商的分词器差异<a href="#五不同厂商的分词器差异"><span>#</span></a></h2><p>虽然算法本质均为 BPE，但各厂商在实现细节、词表大小、预处理方式上存在差异。这直接决定了<strong>能否在本地精确计算 token 数</strong>，以及<strong>相同文本在不同模型间的成本差异</strong>。</p>

<table><thead><tr><th>厂商</th><th>工具/方案</th><th>开源情况</th><th>词表大小</th><th>关键特征</th></tr></thead><tbody><tr><td><strong>OpenAI</strong></td><td>tiktoken</td><td>完全开源</td><td>50K → 100K → 200K（GPT-4o）</td><td>纯 byte-level BPE，本地可精确计算</td></tr><tr><td><strong>Anthropic</strong></td><td>自研 BPE 变体</td><td>完全闭源</td><td>约 100K（推测）</td><td>仅能通过 <code>count_tokens</code> API 查询，无法离线计算</td></tr><tr><td><strong>Google</strong></td><td>SentencePiece + BPE</td><td>开源</td><td>约 256K（Gemini）</td><td>空格替换为 <code>▁</code>，原生支持多语言</td></tr><tr><td><strong>Meta</strong></td><td>SentencePiece + BPE</td><td>开源</td><td>32K（Llama 2）→ 128K（Llama 3）</td><td>基于 SentencePiece 框架的 BPE 实现</td></tr></tbody></table><p>OpenAI 的透明度最高，通过 <code>pip install tiktoken</code> 即可在本地精确计算任意字符串的 token 数与 token ID。Anthropic 透明度最低，分词器从未公开，社区曾通过监听 streaming 流量逆向 token 边界。Google 的 SentencePiece 存在一个独特设计：<strong>将空格视为普通字符</strong>，以 <code>▁</code>（U+2581）替代，因此 <code>"This is a test"</code> 在 SentencePiece 中先转为 <code>"▁This▁is▁a▁test"</code> 再行切分。该设计的工程意义在于<strong>完全语言无关</strong>——中文、日文、泰文等无空格语言不再需要特殊处理，与英文采用统一流程。这也是 Gemini 在多语言场景表现优于早期 GPT 的原因之一。</p></section>
<section><h2>六、LLM 实际处理的对象<a href="#六llm-实际处理的对象"><span>#</span></a></h2><p>回到核心问题：<strong>LLM 处理的是文字还是数字？</strong></p><p><strong>全流程均为数字，更准确地说是高维空间中的向量。</strong> LLM 本质是一个超大规模的数学函数，输入与输出均为数字。模型<strong>不识别</strong> “hello”、“你好” 等字符串——这些字符序列对模型内部计算而言不具备任何含义。</p><p>完整的”文字 → 数字 → 文字”流程如下：</p><p><strong>Part 1：输入 → 模型内部</strong></p><div><div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>'Hello world'</p></span></div><div><span><p>Tokenizer<br /><br />切子词</p></span></div><div><span><p>['Hello',<br /><br />' world']</p></span></div><div><span><p>查 vocab.json</p></span></div><div><span><p>Token IDs<br /><br />[13225, 2375]</p></span></div><div><span><p>Embedding<br /><br />查矩阵</p></span></div><div><span><p>高维向量</p></span></div>
</div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>'Hello world'</p></span></div><div><span><p>Tokenizer<br /><br />切子词</p></span></div><div><span><p>['Hello',<br /><br />' world']</p></span></div><div><span><p>查 vocab.json</p></span></div><div><span><p>Token IDs<br /><br />[13225, 2375]</p></span></div><div><span><p>Embedding<br /><br />查矩阵</p></span></div><div><span><p>高维向量</p></span></div>
</div></div></div><p><strong>Part 2：模型推理 → 输出</strong></p><div><div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>Transformer<br /><br />多层运算</p></span></div><div><span><p>概率分布<br /><br />(≈20 万)</p></span></div><div><span><p>Sampler<br /><br />采样</p></span></div><div><span><p>token ID<br /><br />例如 4842</p></span></div><div><span><p>Detokenizer<br /><br />反查词表</p></span></div><div><span><p>' Paris'</p></span></div>
</div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>Transformer<br /><br />多层运算</p></span></div><div><span><p>概率分布<br /><br />(≈20 万)</p></span></div><div><span><p>Sampler<br /><br />采样</p></span></div><div><span><p>token ID<br /><br />例如 4842</p></span></div><div><span><p>Detokenizer<br /><br />反查词表</p></span></div><div><span><p>' Paris'</p></span></div>
</div></div></div><p>其中一个关键中间步骤是 <strong>Embedding（嵌入层）</strong>。仅有 token ID 不足以支撑模型计算——整数 13225 与 13224 之间不存在任何语义关系，无法直接参与运算。因此模型内部维护一张大规模的 <strong>Embedding 矩阵</strong>，将每个 token ID 映射为一个高维向量（GPT-3 为 12288 维，Llama 3 为 4096 维）。该矩阵<strong>通过训练得到</strong>——训练过程中模型自主学习”语义接近的 token，向量也应当接近”的特性。训练完成后，<code>"king"</code> 与 <code>"queen"</code> 的向量距离较小，<code>"happy"</code> 与 <code>"joyful"</code> 的向量距离较小，著名的等式 <strong>king − man + woman ≈ queen</strong> 在该向量空间中近似成立。</p><p>模型的全部”推理”过程发生在向量空间内。模型接收一串向量，经过多层矩阵乘法与非线性变换，最终输出一个<strong>长度等于词表大小</strong>的概率分布，表示”下一个 token 在词表中每一个候选位置的概率”。采样器从该分布中选出一个 token，<strong>追加至输入末尾</strong>，再次输入模型预测下一个 token——如此循环，直至模型输出表示终止的特殊 token <code>&lt;end_of_text&gt;</code>。该机制称为 <strong>autoregressive generation（自回归生成）</strong>，是所有 GPT 类模型的统一生成原理。</p><div><div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>否</p></span></div><div><span><p>是</p></span></div><div><span><p>初始输入<br /><br />token 序列</p></span></div><div><span><p>模型预测<br /><br />下一个 token</p></span></div><div><span><p>采样得到<br /><br />新 token</p></span></div><div><span><p>追加至序列末尾</p></span></div><div><span><p>是否为<br /><br />结束 token?</p></span></div><div><span><p>Detokenize<br /><br />输出完整字符串</p></span></div>
</div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>否</p></span></div><div><span><p>是</p></span></div><div><span><p>初始输入<br /><br />token 序列</p></span></div><div><span><p>模型预测<br /><br />下一个 token</p></span></div><div><span><p>采样得到<br /><br />新 token</p></span></div><div><span><p>追加至序列末尾</p></span></div><div><span><p>是否为<br /><br />结束 token?</p></span></div><div><span><p>Detokenize<br /><br />输出完整字符串</p></span></div>
</div></div></div></section>
<section><h2>七、由该机制衍生的常见现象<a href="#七由该机制衍生的常见现象"><span>#</span></a></h2><p>理解”LLM 仅处理数字、不处理字符”这一前提后，许多常见现象可获得统一解释。</p>

<table><thead><tr><th>现象</th><th>原因</th></tr></thead><tbody><tr><td>早期GPT 无法准确统计 “strawberry” 中字母 r 的数量</td><td>模型看到的是 <code>["str", "aw", "berry"]</code> 三个 token ID，<strong>字母层级的信息已丢失</strong></td></tr><tr><td>模型偶尔拼写错误</td><td>模型并非在”拼字母”，而是在”接龙 token”，罕见词易接错</td></tr><tr><td><code>"hello"</code> 与 <code>" hello"</code> 输出不同</td><td>二者是<strong>两个完全不同的 token</strong>，对应不同向量</td></tr><tr><td>中文体验弱于英文</td><td>中文 token 在训练语料中占比低，对应的 embedding 训练不充分</td></tr><tr><td>微调（Fine-tuning）能改变模型行为</td><td>微调即调整 Embedding 矩阵与 Transformer 内部参数</td></tr><tr><td>RAG 成本低于微调</td><td>RAG 仅在输入端追加 token，不修改模型参数；微调实际修改模型内部权重</td></tr><tr><td>context window 溢出导致”遗忘”</td><td>模型仅能感知 context 内的 token，溢出部分不可见</td></tr><tr><td>同等内容中文调用 API 成本更高</td><td>中文每字 1–2 token，英文常用词单个仅 1 token，token 数相差 2–3 倍</td></tr></tbody></table></section>
<section><h2>八、核心结论<a href="#八核心结论"><span>#</span></a></h2><ol>
<li>
<p><strong>自然语言在 LLM 内部不存在。</strong> 模型内部仅有 token ID，且 token ID 会被立即转换为向量。</p>
</li>
<li>
<p><strong>Tokenizer 是人类世界与模型世界之间唯一的接口。</strong> 理解 Tokenizer 即理解 LLM 工程问题的一半。</p>
</li>
<li>
<p><strong>token ID 本质上是按频率排序的索引表。</strong> ID 越小越高频，ID 越大越罕见。</p>
</li>
<li>
<p><strong>BPE 的核心思想：以有限子词表覆盖无限词汇组合。</strong></p>
</li>
<li>
<p><strong>LLM 不读字符，它执行数学运算。</strong></p>
</li>
</ol></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/llm-context/</id>
      <title type="text">Context：LLM 的工作记忆与上下文工程</title>
      <published>2026-06-19T00:00:00.000Z</published>
      <updated>2026-06-19T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/llm-context/"/>
      <summary type="text">深入解析 Context 的内部构成、Token 占比结构、API 无状态性以及上下文腐烂（Context Rot）应对策略</summary>
      <content type="html"><![CDATA[<section><h2>一、问题的起点<a href="#一问题的起点"><span>#</span></a></h2><p>理解大语言模型（LLM）的”记忆”机制，最常见的误区是将 context 类比为”对话历史”。事实上 context 远比对话历史复杂——<strong>它包含 system prompt、工具定义、MCP 注册、tool result、thinking 块等大量用户不可见的内容</strong>，对话历史仅是其中一小部分。更进一步的误区是把 context 混同于模型的”知识”——事实上模型的知识固化在训练好的权重中，与 context 完全独立。</p><p>Context 的精确定义来自 Anthropic 官方文档：<strong>Context 是 LLM 在生成响应时能够引用的全部 token 序列，包括即将输出的响应本身</strong>。它是模型的”工作记忆”，每次 API 调用现场构造，调用结束即清空。理解这一点是后续所有 Agent 工程问题（记忆、压缩、检索、Agent 编排）的起点。</p><p>要理解 context 为什么是 Agent 工程的核心问题、为什么”context 越大越好”是错觉、为什么 RAG / Compaction / Subagent 等技术都为它而生，前提是搞清楚：<strong>context 在工程上由什么构成、它如何累积、它的边界在哪里、为何会”腐烂” （Context rot）</strong>。</p></section>
<section><h2>二、Context 的内部构成<a href="#二context-的内部构成"><span>#</span></a></h2><p>Context 在工程上是一个结构化的 messages 数组，由四种 role 与多种 content block 组成。四种 role 分别承担不同职责：<strong>system</strong> 定义全局规则、人设、输出约束，<strong>user</strong> 是人类输入，<strong>assistant</strong> 是模型回复，<strong>tool</strong> 是工具调用的执行结果。API 强制约束第一条 message 必须是 user，user 与 assistant 必须严格交替，tool 消息必须紧跟一个发起调用的 assistant。Anthropic 官方明确说明 system 在训练时被赋予更高优先级——即使用户在对话中说”忽略前面的指令”，system 中写的约束通常依然被遵守，这是 system 这个 role 存在的根本意义。</p><p>一条 message 内部还可继续拆分为多种 content block：普通 text 块、image 块（仅 user 可用）、tool_use 块（assistant 决定调用工具）、tool_result 块（工具返回值）、thinking 块（reasoning 模型的内部推理）、document 块(PDF 等结构化文档)。一个反直觉的细节是：<strong>tool_result 的 role 是 user 而非 tool</strong>，因为 Anthropic 的设计逻辑是工具执行器站在用户侧，把执行结果”递给”模型，所以包装成 user 消息注入。</p><p>各部分的 token 占比直接决定 Agent 的成本结构与可用容量。下表列出实战中典型的 token 占用情况：</p>

<table><thead><tr><th>组成部分</th><th>典型占用</th><th>备注</th></tr></thead><tbody><tr><td>System prompt</td><td>200–3000 tokens</td><td>复杂 Agent 可上万</td></tr><tr><td>工具定义（每个）</td><td>200–800 tokens</td><td>接入 10 个工具就是几千</td></tr><tr><td>MCP 自动注册（每个 server）</td><td>数千 tokens</td><td>多 server 场景轻松上万</td></tr><tr><td>历史 user 消息</td><td>小</td><td>单条几十到几百</td></tr><tr><td>历史 assistant 输出</td><td>中</td><td>单条几百到几千</td></tr><tr><td><strong>tool_result</strong></td><td><strong>每次几百到几万</strong></td><td><strong>Agent context 最大消耗</strong></td></tr><tr><td>Thinking 块</td><td>几百到几千</td><td>reasoning 模型显著占用</td></tr></tbody></table><p><strong>Agent 系统中，tool_result 才是 context 真正的消耗大头</strong>。一次代码库搜索可能返回 10KB 文本，一次数据库查询可能返回 50KB JSON，这些数据原样塞回 context，几轮工具调用下来 context 就满了。所有 context 压缩策略，第一刀都砍向 tool_result。</p></section>
<section><h2>三、API 的无状态性<a href="#三api-的无状态性"><span>#</span></a></h2><p>Anthropic 官方文档原文：<strong>“The Messages API is stateless, which means that you always send the full conversational history to the API.”</strong></p><p>无状态是计算机科学的术语，意思是服务端不保存任何会话信息，每次请求必须自带所有需要的内容。这对 Agent 工程产生了根本性影响：<strong>模型本身从不记忆任何东西，所谓的”会话连续性”完全是应用层把历史回传给 API 的工程结果</strong>。</p><p>多轮对话的实际机制是这样的：第一轮用户说”我叫 Michael”，应用发给 API；第二轮用户问”我叫什么名字”，应用必须<strong>把第一轮的内容一起回传</strong>，模型才能”记得”。若应用只发当前问题不回传历史，模型会真实地回答”我不知道”——它从未”记住”过任何东西。这一机制带来的工程后果是：<strong>所有看起来像”记忆”的能力（ChatGPT memory、Claude Projects、Copilot personalization）本质上都是应用层在每次请求时把相关信息拼接到 context 里</strong>。</p><div><div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>第 1 轮<br /><br />User: 我叫 Michael</p></span></div><div><span><p>API<br /><br />记录: 无</p></span></div><div><span><p>Assistant: 你好 Michael</p></span></div><div><span><p>第 2 轮<br /><br />应用层拼装完整历史</p></span></div><div><span><p>发给 API:<br /><br />[User: 我叫 Michael,<br /><br />Assistant: 你好 Michael,<br /><br />User: 我叫什么名字]</p></span></div><div><span><p>API 看见完整上下文<br /><br />回答: 你叫 Michael</p></span></div>
</div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>第 1 轮<br /><br />User: 我叫 Michael</p></span></div><div><span><p>API<br /><br />记录: 无</p></span></div><div><span><p>Assistant: 你好 Michael</p></span></div><div><span><p>第 2 轮<br /><br />应用层拼装完整历史</p></span></div><div><span><p>发给 API:<br /><br />[User: 我叫 Michael,<br /><br />Assistant: 你好 Michael,<br /><br />User: 我叫什么名字]</p></span></div><div><span><p>API 看见完整上下文<br /><br />回答: 你叫 Michael</p></span></div>
</div></div></div></section>
<section><h2>四、Context 的累积机制<a href="#四context-的累积机制"><span>#</span></a></h2><p>由于 API 无状态，多轮对话的 context 必然单调递增。Anthropic 官方文档将此过程总结为三条规律：<strong>progressive token accumulation（渐进累积）</strong>——每轮的 user 与 assistant 消息被永久保留；<strong>linear growth pattern（线性增长）</strong>——context 占用随轮次线性上涨；<strong>capacity ceiling（容量天花板）</strong>——所有累积内容加上即将输出的内容，总和不得超过模型最大 context。</p><div><div><div><div><span></span></div><div><span><p>否</p></span></div><div><span></span></div><div><span><p>是</p></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>用户第 n 轮输入</p></span></div><div><span><p>历史 + 新输入<br /><br />是否超过阈值?</p></span></div><div><span><p>拼接完整历史</p></span></div><div><span><p>发送给 LLM</p></span></div><div><span><p>选择策略</p></span></div><div><span><p>截断旧轮次</p></span></div><div><span><p>摘要压缩旧历史</p></span></div><div><span><p>RAG 检索相关片段</p></span></div><div><span><p>重组 prompt<br /><br />system + 压缩历史 + 最近轮 + 新输入</p></span></div><div><span><p>返回回复</p></span></div><div><span><p>更新对话状态<br /><br />必要时触发后台压缩</p></span></div>
</div><div><div><span></span></div><div><span><p>否</p></span></div><div><span></span></div><div><span><p>是</p></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>用户第 n 轮输入</p></span></div><div><span><p>历史 + 新输入<br /><br />是否超过阈值?</p></span></div><div><span><p>拼接完整历史</p></span></div><div><span><p>发送给 LLM</p></span></div><div><span><p>选择策略</p></span></div><div><span><p>截断旧轮次</p></span></div><div><span><p>摘要压缩旧历史</p></span></div><div><span><p>RAG 检索相关片段</p></span></div><div><span><p>重组 prompt<br /><br />system + 压缩历史 + 最近轮 + 新输入</p></span></div><div><span><p>返回回复</p></span></div><div><span><p>更新对话状态<br /><br />必要时触发后台压缩</p></span></div>
</div></div></div><p>在 Agent 场景下，问题更严峻。普通 chatbot 每轮可能增加 1–2K tokens，Agent 每轮可能伴随多次工具调用——一次搜索返回 5KB JSON，一次文件读取返回 12KB 文本，一次 API 查询返回 8KB 数据——单轮 context 增量可达 20K 以上。Claude Code 官方文档明确指出：<strong>在用户输入第一条消息之前，context 中已被系统提示、CLAUDE.md、所有 MCP 工具定义、Skill 描述、路径作用域规则等内容占满</strong>，一个复杂任务可能开局就消耗几万 token。这是 Agent 比 chatbot 烧 context 烧得快得多的根本原因，也是 context 工程在 Agent 系统中被推到第一优先级的原因。</p></section>
<section><h2>五、Context 是输入与输出共享的同一池子<a href="#五context-是输入与输出共享的同一池子"><span>#</span></a></h2><p>一个被大量误解的工程事实：<strong>context window 是输入与输出共享的同一额度，不是只算输入</strong>。若模型 context 上限为 200K，输入塞入 199K，留给输出的仅剩 1K。许多 API 调用中模型回答突然戛然而止、<code>max_tokens</code> 设大也写不完的根源就在这里。</p><p>主流模型当前的 context 容量参考：GPT-5.4 在 API 中标称 1.05M tokens（max output 128K），Claude Sonnet 4.6 支持原生 1M tokens，Gemini 2.5 Pro 同样支持 1M tokens 量级。需要注意 max output 通常远小于 context 上限——模型可以”看到”百万 token，但一次性”输出”不超过十几万 token。这是工程决策中容易踩坑的细节。</p></section>
<section><h2>六、Context Rot：长上下文性能退化<a href="#六context-rot长上下文性能退化"><span>#</span></a></h2><p>业内一度认为 context window 越大越好，但 2025 年 7 月 Chroma 团队发布的《Context Rot》技术报告系统性推翻了这一假设。该研究测试了 GPT-4.1、Claude 4、Gemini 2.5、Qwen3 等 18 个前沿模型，结论极为明确：<strong>模型并不会均匀地使用 context；随着输入长度增加，模型表现愈发不可靠</strong>。Anthropic 官方文档已正式采用 context rot 这一术语，并在 context windows 页面警告：“随着 token 数量增加，准确率与召回率会衰减——所以精心策划放什么进 context，和能放多少一样重要。”</p><p>Context rot 必须与 context 溢出严格区分。<strong>溢出是二元失败</strong>——超过 token 上限时请求被截断或拒绝，会报错；<strong>context rot 是连续退化</strong>——在远未达到上限时输出质量已经悄悄下降，不报错也不提示。一个 200K context 的模型，可能在 50K tokens 时就已出现明显性能下降。Chroma 研究的核心贡献是揭示：<strong>衡量上下文质量的正确指标不是容量，而是信噪比（signal-to-noise ratio）</strong>。</p><p>Context rot 的成因可从三个层面理解。<strong>架构层面</strong>：Transformer 的 self-attention 要求每个 token 与所有其他 token 建立 n² 关系，序列越长注意力越被稀释。<strong>训练分布层面</strong>：训练语料绝大多数是中短文本，长距离依赖在训练分布中被低估，模型对长上下文的推理能力本身就训练不足。<strong>应用层面</strong>：Agent 在搜索、探索、回溯过程中持续累积噪声 token，这些噪声直接降低后续每一步的输出质量。</p><div><div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>短上下文<br /><br />&lt; 8K<br /><br />性能高且稳定</p></span></div><div><span><p>中等上下文<br /><br />8K – 50K<br /><br />开始出现波动</p></span></div><div><span><p>长上下文<br /><br />50K – 200K<br /><br />准确率明显下降</p></span></div><div><span><p>超长上下文<br /><br />&gt; 200K<br /><br />退化加剧但未溢出</p></span></div><div><span><p>接近 context 上限<br /><br />溢出截断</p></span></div>
</div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>短上下文<br /><br />&lt; 8K<br /><br />性能高且稳定</p></span></div><div><span><p>中等上下文<br /><br />8K – 50K<br /><br />开始出现波动</p></span></div><div><span><p>长上下文<br /><br />50K – 200K<br /><br />准确率明显下降</p></span></div><div><span><p>超长上下文<br /><br />&gt; 200K<br /><br />退化加剧但未溢出</p></span></div><div><span><p>接近 context 上限<br /><br />溢出截断</p></span></div>
</div></div></div></section>
<section><h2>七、大窗口模型是否一定更好<a href="#七大窗口模型是否一定更好"><span>#</span></a></h2><p>由 context rot 引出的精确判断：<strong>窗口大小决定”能不能做”，模型代际决定”做得好不好”</strong>。</p><p>在两者都能装得下的区间（例如同为 50K 输入的小数据量场景），大窗口模型并不天然更好——其表现主要由模型本身的能力决定，不由窗口上限决定。许多场景下感受到的”大窗口模型表现更好”，真正起作用的是”大窗口模型通常是更新一代、训练更充分”，而非”窗口大”这个属性本身。但一旦数据量逼近或超过小窗口上限，大窗口模型就拥有绝对优势——因为小窗口模型已经直接出局。</p><p>此外，大窗口模型在工程上还有两个隐性价值。<strong>第一是 buffer 余量</strong>：Agent 的 context 用量不可预测，大窗口允许 compaction 触发更晚，对应更少的额外 LLM 调用与更少的信息损失。<strong>第二是新一代模型的 long-context 训练本身更充分</strong>：Gemini 2.5、Claude Sonnet 4.6 在 1M context 上的表现已显著优于上一代模型在 200K 上的表现，context rot 在变弱，只是变弱的速度跟不上容量增长的速度。</p></section>
<section><h2>八、Context Engineering：新一代工程范式<a href="#八context-engineering新一代工程范式"><span>#</span></a></h2><p>Anthropic 在 2025 年 9 月 29 日发布博文 <em>Effective Context Engineering for AI Agents</em>，正式将 <strong>context engineering</strong> 定义为 prompt engineering 的自然演进。两者的本质差异在于关注对象与时间维度：<strong>Prompt engineering 关注 system prompt 的写法</strong>——一次性的、离散的、静态的写作任务；<strong>Context engineering 关注每次推理时往 context 里放什么</strong>——持续的、动态的、跨轮次的策划过程。在多轮 Agent 场景中，每一个 inference loop 都会产生新数据，这些数据是否应进入下一轮 context、以何种形式压缩、何时丢弃，构成了 context engineering 的核心工程问题。</p><p>Anthropic 给出的核心原则可归纳为五条：<strong>第一</strong>，将 context 视作稀缺资源进行预算管理——由于 context rot 的存在，无脑塞入更多内容只会降低质量，每个进入 context 的 token 都应有明确价值；<strong>第二</strong>，system prompt 应在”明确”与”灵活”之间取得平衡——过度工程化的硬规则脆弱易碎，过于模糊的指导无法引导行为；<strong>第三</strong>，工具定义是 Agent 与环境的契约——工具集应小而精，每个工具的输入输出、副作用、错误模式应清晰可预测；<strong>第四</strong>，长会话必须有压缩机制；<strong>第五</strong>，subagent 模式隔离上下文污染。</p></section>
<section><h2>九、Context 管理的六类工程手段<a href="#九context-管理的六类工程手段"><span>#</span></a></h2><p>实践中存在六类主流的 context 管理手段，分别对应不同层次的工程问题。各方案的信息损失、实现复杂度、适用场景差异显著：</p>

<table><thead><tr><th>方案</th><th>信息损失</th><th>复杂度</th><th>主要适用场景</th></tr></thead><tbody><tr><td><strong>截断</strong>（滑动窗口）</td><td>高</td><td>极低</td><td>简单 chatbot</td></tr><tr><td><strong>摘要（Compaction）</strong></td><td>中</td><td>中</td><td>长会话 Agent</td></tr><tr><td><strong>Tool Result Clearing</strong></td><td>低</td><td>中</td><td>工具调用密集场景</td></tr><tr><td><strong>Subagent 隔离</strong></td><td>极低</td><td>高</td><td>复杂任务分解</td></tr><tr><td><strong>RAG</strong>（检索式补充）</td><td>取决于检索质量</td><td>高</td><td>跨会话长期记忆</td></tr><tr><td><strong>Code Execution with MCP</strong></td><td>极低</td><td>极高</td><td>大量 MCP 工具场景</td></tr></tbody></table><p><strong>截断</strong>是最朴素的方案，超过阈值丢掉最早几轮对话，实现成本零但早期重要信息直接丢失。<strong>摘要（Compaction）</strong> 是 Claude Code 的 <code>/compact</code> 命令的核心机制——让另一个 LLM 调用把早期对话总结成结构化摘要，保留任务目标、关键决策、文件状态，丢弃探索过程、被否决的方案、详细 tool_result。摘要由 LLM 生成本身消耗 tokens，且不可逆——一旦压缩被丢的细节就回不来了，但这是当前长会话 Agent 的主流方案。<strong>Tool Result Clearing</strong> 是专门针对 tool_result 吞噬者的优化——清除中间探路失败的 tool_result 内容但保留对应的 tool_use 调用记录（否则 API 会因不匹配而报错）。<strong>Subagent 隔离</strong> 是结构性方案：把大量文件读取、搜索操作放入独立 subagent 的 context 中执行，主对话只接收 subagent 返回的摘要，主 context 始终保持干净。<strong>RAG</strong> 处理跨会话长期记忆，将历史会话/文档存在向量库中，每次请求时只检索与当前问题相关的几段注入 context。</p><p><strong>Code Execution with MCP</strong> 是 Anthropic 2025-11 提出的最新方案，应对”工具爆炸”问题——当 Agent 接入大量 MCP 工具时，工具定义本身就能塞满 context，解决方案是让 Agent 生成代码调用工具而非直接调用，代码在沙箱执行，仅最终结果回 context。</p><p>成熟的 Agent 系统通常组合使用多种方案。Claude Code 同时用了 system prompt 优化、subagent、tool result clearing、<code>/compact</code> 摘要四种机制。</p></section>
<section><h2>十、Prompt Caching：成本优化的关键机制<a href="#十prompt-caching成本优化的关键机制"><span>#</span></a></h2><p>Anthropic 的 prompt caching 是 context 工程中无法跳过的成本优化手段。其机制是将稳定的前缀（system prompt、工具定义、长背景资料）缓存在服务端，<strong>5 分钟内的后续请求只为变化部分付费</strong>。命中缓存的 token 价格降至正常输入的 10%，首次写入价格为 125%。对于多轮会话或固定模板场景，节省比例可达 80–92%。</p><p>缓存遵循严格的前缀层级：<strong>tools → system → messages</strong>，任一层级变更会使该层及之后的所有缓存失效。具体规则：修改工具定义会使整张缓存失效；修改 system 会使 system + messages 缓存失效；修改 tool_choice 仅使 messages 缓存失效。模型对缓存有最小 token 门槛——Claude Sonnet/Haiku 系列要求 ≥1024 tokens，Opus 系列要求 ≥4096 tokens，低于门槛的内容不被缓存。这一机制在工程上的直接影响是：<strong>工具集应结构稳定、版本受控</strong>，频繁修改工具定义会导致 caching 优化完全失效。</p></section>
<section><h2>十一、Context 与 Memory 的关系<a href="#十一context-与-memory-的关系"><span>#</span></a></h2><p>容易混淆的一对概念是 <strong>context</strong> 与 <strong>memory</strong>。<strong>Context 指单次推理请求中模型实际看到的全部 token 序列</strong>，是模型的工作记忆，调用结束随请求消失。<strong>Memory 指跨会话保留的信息</strong>，由应用层实现，通常落地在数据库、向量库、知识图谱中。模型本身没有 memory，所谓”模型记得用户偏好”本质上是应用层在每次请求时将相关 memory 提取并注入到 context 中。</p><p>二者的关系可类比为：<strong>Memory 是磁盘，Context 是 RAM</strong>。每次请求时，应用层从 memory 中取出与当前任务相关的片段，连同 system prompt、对话历史、工具定义一起组装成 context 交给模型；模型完成推理后，应用层决定是否将本轮的新信息回写到 memory。</p><div><div><div><div><span><p>检索相关片段</p></span></div><div><span><p>system + history<br /><br />+ retrieved</p></span></div><div><span></span></div><div><span><p>生成 + 新信息</p></span></div><div><span><p>写回</p></span></div><div><span><p>Memory<br /><br />向量库 / KG / DB<br /><br />持久化</p></span></div><div><span><p>Orchestrator<br /><br />组装 context</p></span></div><div><span><p>Context Window<br /><br />单次工作记忆</p></span></div><div><span><p>LLM</p></span></div>
</div><div><div><span><p>检索相关片段</p></span></div><div><span><p>system + history<br /><br />+ retrieved</p></span></div><div><span></span></div><div><span><p>生成 + 新信息</p></span></div><div><span><p>写回</p></span></div><div><span><p>Memory<br /><br />向量库 / KG / DB<br /><br />持久化</p></span></div><div><span><p>Orchestrator<br /><br />组装 context</p></span></div><div><span><p>Context Window<br /><br />单次工作记忆</p></span></div><div><span><p>LLM</p></span></div>
</div></div></div></section>
<section><h2>十二、由该机制衍生的常见现象<a href="#十二由该机制衍生的常见现象"><span>#</span></a></h2><p>理解 context 是模型的”工作记忆”、API 无状态、context window 输入输出共享、context rot 存在等核心事实后，许多平时让人困惑的现象可获得统一解释。</p>

<table><thead><tr><th>现象</th><th>原因</th></tr></thead><tbody><tr><td>同一个 Claude 网页对话聊得太久会前后矛盾</td><td>早期对话被 compaction 摘要时丢失了关键细节</td></tr><tr><td>API 调用第二轮完全失忆</td><td>API 无状态，应用未回传第一轮的 messages</td></tr><tr><td>ChatGPT 偶尔”忘了”之前提过的事</td><td>该信息未进入当前会话的 context（memory 未匹配或已超容量）</td></tr><tr><td>同样 prompt 在 GPT-4 与 GPT-5 输出截然不同</td><td>模型代际差异，与 context 无关</td></tr><tr><td>1M context 模型在 50K 输入上感觉”更聪明”</td><td>主要是模型代际差异，窗口大小本身贡献小</td></tr><tr><td>长对话末尾模型答非所问</td><td>context rot——长 context 上准确率下降</td></tr><tr><td>Agent 跑几轮后突然变慢</td><td>tool_result 累积导致 context 接近上限，处理变慢</td></tr><tr><td>修改工具定义后 prompt caching 失效</td><td>工具定义在 tools 层级，变更使整张缓存失效</td></tr><tr><td>同样问题某次答对某次答错</td><td>不同会话 context 内容不同，导致行为差异</td></tr></tbody></table></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/agent/</id>
      <title type="text">什么是 Agent：本质、边界与架构机制</title>
      <published>2026-06-07T00:00:00.000Z</published>
      <updated>2026-06-07T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/agent/"/>
      <summary type="text">系统性剖析 AI Agent 的本质定义、与 Workflow 及 MCP 的边界划分，以及 ReAct 循环架构机制</summary>
      <content type="html"><![CDATA[<blockquote><p>整理时间：2026-06-07</p></blockquote>
<hr />
<section><h2>一、什么是 Agent<a href="#一什么是-agent"><span>#</span></a></h2><p>在开始之前，可以先看一下官方的定义。</p><section><h3>官方定义<a href="#官方定义"><span>#</span></a></h3><p><strong>Anthropic（Building Effective Agents, 2024.12）</strong>：</p><blockquote><p>“Agents are systems where LLMs dynamically direct their own processes and tool usage, maintaining control over how they accomplish tasks.”（Agent 是这样一种系统：由 LLM 动态决定自己的处理过程和工具调用，并对”如何完成任务”保持控制权。）</p></blockquote><p><strong>Google Cloud</strong>：</p><blockquote><p>“AI agents are software systems that use AI to pursue goals and complete tasks on behalf of users. They show reasoning, planning, and memory and have a level of autonomy to make decisions, learn, and adapt.”（Agent 是用 AI 代表用户去追求目标、完成任务的软件系统，具备推理、规划、记忆能力，并拥有一定的自主决策、学习和适应能力。）</p></blockquote><p><strong>Microsoft Learn</strong>：</p><blockquote><p>“Agents are dynamic, goal-oriented systems that can reason, plan, and act on behalf of users.” Agent 的三个核心组件是 <strong>Model（LLM 作为推理引擎）、Instructions（目标、行为和约束）、Tools（获取知识或执行动作的能力）</strong>。</p></blockquote><p>三家定义合起来看，Agent 的本质有三层意思：</p><p>第一，它是一个<strong>软件系统</strong>，不是单一模型，也不是单一函数。第二，它的<strong>大脑是 LLM</strong>，由 LLM 在运行时即时决定”下一步做什么”。第三，它带着<strong>目标</strong>工作——用户给的是结果要求，不是步骤指令；具体路径由 Agent 自己摸索。</p><p>LLM（Large Language Model，大语言模型）是 Agent 的核心零件，但 Agent ≠ LLM。LLM 本身是无状态的”下一个 token 预测器”，喂文字、吐文字；Agent 在 LLM 外面加了工具调用、循环控制、记忆，使它能”做事”而不仅是”说话”。</p></section><section><h3>一个具体例子<a href="#一个具体例子"><span>#</span></a></h3><p>用户对 Agent 说：“帮我安排一个下周和 Sherry 的 30 分钟 1on1。”</p><p>内部发生的事情大致是：Agent 调日历工具查双方下周空闲时段 → 选出 3 个备选 → 调发邮件工具向 Sherry 询问偏好 → 收到回复后调建会议工具创建会议 → 把结果汇报给用户。这一连串决策不是程序员写死的 if/else，而是 LLM 看着目标和工具列表即时决定的。</p></section><section><h3>简而言之<a href="#简而言之"><span>#</span></a></h3><blockquote><p><strong>Agent 是以 LLM 为决策核心、能自主选择工具与路径、以达成用户目标为终点的软件系统。</strong></p></blockquote><hr /></section></section>
<section><h2>二、为什么叫 Agent<a href="#二为什么叫-agent"><span>#</span></a></h2><p>英文 “agent” 来源于词根 <strong>agency</strong>，意为”代理权、代为行动的能力”。在法律、商业语境里，agent 指被授权代他人办事的人（房产 agent、保险 agent）。把这个词用在 AI 系统上，强调的不是它”多聪明”，而是它<strong>拥有代理权——可以代用户去思考、查询、调用工具、产出结果</strong>。这一点是它和传统软件、传统 LLM 应用最根本的区别。</p><p>判定一个系统是不是 Agent，有一条非常实用的标准：<strong>下一步动作是写死在代码里的，就不是 Agent；下一步是 LLM 实时决定的，才是 Agent</strong>。</p><hr /></section>
<section><h2>三、Agent 与几个相邻概念的边界<a href="#三agent-与几个相邻概念的边界"><span>#</span></a></h2><section><h3>Agent vs LLM Wrapper（聊天界面算 Agent 吗）<a href="#agent-vs-llm-wrapper聊天界面算-agent-吗"><span>#</span></a></h3><p>LLM Wrapper（壳子）指仅在 LLM 外面套了一层 UI 和提示模板的应用。判定方法很直观：如果同样的输入复制到原生 ChatGPT 能得到一样的结果，那它就是 Wrapper。</p><p>ChatGPT、Claude、Gemini 的聊天界面在”纯文字问答”模式下并不是 Agent，更接近 Wrapper。但当聊天界面开启了网页搜索、Code Interpreter、Computer Use 等能力，让模型自己决定调工具，它就升级成了 Agent。Claude Code、Cursor 这类编程助手则是非常典型的现代 Agent，因为它们会自己读文件、改代码、跑测试、根据结果决定下一步动作。</p></section><section><h3>Agent vs Workflow<a href="#agent-vs-workflow"><span>#</span></a></h3><p>Anthropic 称：</p><blockquote><p>“Workflows are systems where LLMs and tools are orchestrated through <strong>predefined code paths</strong>. Agents, on the other hand, are systems where <strong>LLMs dynamically direct their own processes and tool usage</strong>.”</p></blockquote><p>也就是说，<strong>Workflow 的执行路径写死在代码里，LLM 只在指定节点干活；Agent 的执行路径由 LLM 在运行时即时决定</strong>。这是两者唯一的、也是根本的分界线。</p><p>人类在 Agent 系统里”设的不是流程”，而是”边界”——告诉它扮演什么角色、有哪些工具可用、什么时候应该停。具体先调哪个工具、调完之后下一步做什么、要不要重试，全部交给 LLM。</p><p>Anthropic 在同一篇文章里给的关键建议是：<strong>能用 Workflow 解决的就不要上 Agent</strong>。Workflow 可预测、好调试、便宜；Agent 灵活但失控风险高、成本也高。只有”路径无法预先确定”的开放任务，才值得用真正的 Agent。</p></section><section><h3>Agent 是不是只是”LLM 套壳”<a href="#agent-是不是只是llm-套壳"><span>#</span></a></h3><p>这是常见的批评，对粗糙产品成立，但对成熟 Agent 系统不成立。Andrew Ng 给出过一个被广泛引用的实验：在 HumanEval 编程基准上，强 LLM 直接零样本回答约 67%；弱 LLM 配上完善的 Agentic Workflow（含反思、工具、规划）能到约 95%。<strong>架构带来的提升可以超过模型本身的提升</strong>。
Agent 外面那层工程，业界叫 <strong>Agent Harness</strong>（代理外骨骼），由工具集、系统提示、上下文管理、循环控制、子 Agent、外部协议接入等组成。说”套壳”低估了这套工程的复杂度。</p></section><section><h3>Agent vs MCP<a href="#agent-vs-mcp"><span>#</span></a></h3><p><a href="/posts/MCP/">MCP</a>（Model Context Protocol，模型上下文协议）是 Anthropic 在 2024 年提出的开放协议，规定了”外部工具如何被 Agent 标准化调用”。它和 Agent 不在同一个层面：</p>

<table><thead><tr><th></th><th>Agent</th><th>MCP</th></tr></thead><tbody><tr><td>本质</td><td>决策系统</td><td>连接协议</td></tr><tr><td>LLM</td><td>有</td><td>无</td></tr><tr><td>角色</td><td>主动决定调用什么</td><td>被动等待被调用</td></tr></tbody></table><p>打个比方：MCP 像 USB-C 标准，Agent 像电脑——电脑里有 CPU 会做决策，USB-C 接口只是规定”外设怎么接进来”。在 MCP 出现之前，每个 Agent 想接一个工具都要单独写一段适配代码，N 个 Agent 接 M 个工具就要写 N×M 套集成。MCP 把这件事标准化了：工具方写一次 MCP Server，所有支持 MCP 的 Agent 都能用，因此被称作 “AI 时代的 USB-C”。</p><hr /></section></section>
<section><h2>四、Agent 的内部结构<a href="#四agent-的内部结构"><span>#</span></a></h2><section><h3>落到代码层面的五样东西<a href="#落到代码层面的五样东西"><span>#</span></a></h3><p>剥开任何一个 Agent 框架，里面通常是这五样：System Prompt（角色和规则的字符串）、Tool Registry（工具清单加 JSON Schema）、Agent Loop（while 循环）、LLM Client（实际调模型 API 的代码）、Memory（短期是消息列表，长期是向量数据库）。</p><p>最核心的是 Agent Loop。它的逻辑非常朴素：把当前上下文喂给 LLM，LLM 输出一段思考——如果思考里说要调工具就调，把结果拼回上下文继续下一轮；如果说已经得到答案就跳出循环返回结果。</p></section><section><h3>ReAct：现代 Agent 的事实标准<a href="#react现代-agent-的事实标准"><span>#</span></a></h3><p>Loop 内部的”思考风格”，业界主流是 <strong>ReAct（Reasoning + Acting，推理与行动交替）</strong>。它让 LLM 每轮显式产出三件事：<strong>Thought（在想什么）、Action（要调什么工具）、Observation（工具返回了什么）</strong>。这种”想一步、做一步、看一步”的循环已成为大多数 Agent 框架的默认推理范式。</p><p>具体形态大致是这样：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Thought: 用户想查自己的 manager，需要先知道用户身份</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>Action: lookup_current_user()</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>Observation: Michael Zhao, employee_id=12345</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>Thought: 有了 employee_id，可以查 manager</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>Action: get_manager(12345)</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>Observation: Akira Yamamoto</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>Thought: 信息够了，可以回答</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>Answer: 你的 manager 是 Akira Yamamoto。</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>最小可运行 Agent 的尺寸<a href="#最小可运行-agent-的尺寸"><span>#</span></a></h3><p>值得记住的一点是，<strong>最小可运行的 Agent 大约 30 行 Python 就能写完</strong>：一个 while 循环、一次 LLM 调用、一次工具调用、消息拼接，仅此而已。Anthropic 原文的态度很明确——“如果能避免就别用框架，大多数 Agent 直接用 LLM API 就能写出来”。LangGraph、CrewAI、Microsoft Agent Framework 这类框架的真正价值是在生产环境里管多 Agent 协作、可观测性、鉴权、容错，而不是 Agent 内核本身有多复杂。</p><hr /></section></section>
<section><h2>五、要不要写代码<a href="#五要不要写代码"><span>#</span></a></h2><p>这取决于站在哪一层。<strong>造 Agent 内核</strong>：要写代码，但其实非常薄。<strong>用低代码平台搭业务 Agent</strong>：可以几乎不写代码，例如 Microsoft Copilot Studio 通过拖拽配置就能搭出一个能跑的 Agent。<strong>给 Agent 提供工具能力</strong>（例如写一个 MCP Server 把企业 API 暴露出去）：必然要写代码，这是后端工程师的活。</p><p>一个 Agent 项目往往三层都涉及——前端 Agent 用低代码配置，工具层用代码实现 MCP Server，更底层的业务 API 用传统后端框架（Spring Boot、Express、FastAPI 等）实现。</p><hr /></section>
<section><h2>六、微软 Agent 生态<a href="#六微软-agent-生态"><span>#</span></a></h2><p>微软的 Agent 栈里有三个关键名字：<strong>Copilot Studio</strong>（低代码 Agent 平台，前身 Power Virtual Agents，面向业务用户）、<strong>Microsoft Agent Framework / MAF</strong>（2025 年 10 月发布预览版的代码优先 SDK，由 Semantic Kernel 和 AutoGen 合并而来，面向 AI 工程师，原生支持 MCP、A2A、OpenAPI）、<strong>Work IQ</strong>（2025 年 Ignite 命名的”工作智能层”，给上层 Agent 提供数据、上下文、工具能力）。这三者构成”底座 + 两种搭建方式”的结构，详细内容另开笔记。</p><div><div><div>🔧 Tool🌐 MCP Server📚 Skill🧠 LLM🤖 Agent🎯 Orchestrator🔧 Tool🌐 MCP Server📚 Skill🧠 LLM🤖 Agent🎯 Orchestrator👤 UserAgentic Loop 开始Agentic Loop 结束"帮我 review 一下这段代码"1判断任务类型2路由到合适的 Agent3prompt + 可用 Skills 清单(只含 description)4"我需要 code-review skill"5加载 SKILL.md 正文(progressive disclosure)6返回完整 SOP7prompt + SOP + 工具清单8"第一步:调用 read_file"9通过 MCP 协议调用10执行 read_file11返回文件内容12标准化结果13把内容喂给 LLM,问下一步14"再调用 run_tests"15调用 run_tests16测试结果17任务完成?18✅ 完成19返回结果20"已完成 review,发现 3 个问题..."21👤 User
</div><div>🔧 Tool🌐 MCP Server📚 Skill🧠 LLM🤖 Agent🎯 Orchestrator🔧 Tool🌐 MCP Server📚 Skill🧠 LLM🤖 Agent🎯 Orchestrator👤 UserAgentic Loop 开始Agentic Loop 结束"帮我 review 一下这段代码"1判断任务类型2路由到合适的 Agent3prompt + 可用 Skills 清单(只含 description)4"我需要 code-review skill"5加载 SKILL.md 正文(progressive disclosure)6返回完整 SOP7prompt + SOP + 工具清单8"第一步:调用 read_file"9通过 MCP 协议调用10执行 read_file11返回文件内容12标准化结果13把内容喂给 LLM,问下一步14"再调用 run_tests"15调用 run_tests16测试结果17任务完成?18✅ 完成19返回结果20"已完成 review,发现 3 个问题..."21👤 User
</div></div></div></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/warpxray/</id>
      <title type="text">利用Xray搭建WARP中转节点</title>
      <published>2025-04-25T00:00:00.000Z</published>
      <updated>2025-04-25T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/warpxray/"/>
      <summary type="text">使用Xray和Cloudflare WARP搭建优化连接的代理中转</summary>
      <content type="html"><![CDATA[<section><h2>1. Xray<a href="#1-xray"><span>#</span></a></h2><section><h3>1. 安装 Xray<a href="#1-安装-xray"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bash</span><span> </span><span>-c</span><span> </span><span>"$(</span><span>curl</span><span> </span><span>-L</span><span> https://github.com/XTLS/Xray-install/raw/main/install-release.sh)"</span><span> </span><span>@</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>2. 配置 Xray<a href="#2-配置-xray"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vim</span><span> </span><span>/usr/local/etc/xray/config.json</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>自行修改配置</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"log"</span><span>: {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"loglevel"</span><span>: </span><span>"warning"</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>5</div></div><div><span>  </span><span>"inbounds"</span><span>: [</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>7</div></div><div><span>      </span><span>"listen"</span><span>: </span><span>"0.0.0.0"</span><span>,</span></div></div><div><div><div>8</div></div><div><span>      </span><span>"port"</span><span>: </span><span>30000</span><span>,</span></div></div><div><div><div>9</div></div><div><span>      </span><span>"protocol"</span><span>: </span><span>"shadowsocks"</span><span>,</span></div></div><div><div><div>10</div></div><div><span>      </span><span>"settings"</span><span>: {</span></div></div><div><div><div>11</div></div><div><span>        </span><span>"method"</span><span>: </span><span>"none"</span><span>,</span></div></div><div><div><div>12</div></div><div><span>        </span><span>"password"</span><span>: </span><span>"password"</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>14</div></div><div><span>      </span><span>"tag"</span><span>: </span><span>"ria-socks-in"</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>17</div></div><div><span>      </span><span>"listen"</span><span>: </span><span>"0.0.0.0"</span><span>,</span></div></div><div><div><div>18</div></div><div><span>      </span><span>"port"</span><span>: </span><span>20000</span><span>,</span></div></div><div><div><div>19</div></div><div><span>      </span><span>"protocol"</span><span>: </span><span>"shadowsocks"</span><span>,</span></div></div><div><div><div>20</div></div><div><span>      </span><span>"settings"</span><span>: {</span></div></div><div><div><div>21</div></div><div><span>        </span><span>"method"</span><span>: </span><span>"none"</span><span>,</span></div></div><div><div><div>22</div></div><div><span>        </span><span>"password"</span><span>: </span><span>"password"</span></div></div><div><div><div>23</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>24</div></div><div><span>      </span><span>"tag"</span><span>: </span><span>"tpc-socks-in"</span></div></div><div><div><div>25</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>26</div></div><div><span><span>  </span></span><span>],</span></div></div><div><div><div>27</div></div><div><span>  </span><span>"outbounds"</span><span>: [</span></div></div><div><div><div>28</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>29</div></div><div><span>      </span><span>"protocol"</span><span>: </span><span>"freedom"</span><span>,</span></div></div><div><div><div>30</div></div><div><span>      </span><span>"settings"</span><span>: {},</span></div></div><div><div><div>31</div></div><div><span>      </span><span>"proxySettings"</span><span>: {</span></div></div><div><div><div>32</div></div><div><span>        </span><span>"tag"</span><span>: </span><span>"freedomout"</span></div></div><div><div><div>33</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>34</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>35</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>36</div></div><div><span>       </span><span>"protocol"</span><span>: </span><span>"socks"</span><span>,</span></div></div><div><div><div>37</div></div><div><span>       </span><span>"settings"</span><span>: {</span></div></div><div><div><div>38</div></div><div><span>         </span><span>"servers"</span><span>: [</span></div></div><div><div><div>39</div></div><div><span><span>           </span></span><span>{</span></div></div><div><div><div>40</div></div><div><span>             </span><span>"address"</span><span>: </span><span>"127.0.0.1"</span><span>,</span></div></div><div><div><div>41</div></div><div><span>             </span><span>"port"</span><span>: </span><span>40000</span></div></div><div><div><div>42</div></div><div><span><span>           </span></span><span>}</span></div></div><div><div><div>43</div></div><div><span><span>         </span></span><span>]</span></div></div><div><div><div>44</div></div><div><span><span>       </span></span><span>},</span></div></div><div><div><div>45</div></div><div><span>       </span><span>"tag"</span><span>: </span><span>"warp-proxy"</span></div></div><div><div><div>46</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>47</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>48</div></div><div><span>      </span><span>"protocol"</span><span>: </span><span>"blackhole"</span><span>,</span></div></div><div><div><div>49</div></div><div><span>      </span><span>"settings"</span><span>: {},</span></div></div><div><div><div>50</div></div><div><span>      </span><span>"tag"</span><span>: </span><span>"blocked"</span></div></div><div><div><div>51</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>52</div></div><div><span><span>  </span></span><span>],</span></div></div><div><div><div>53</div></div><div><span>  </span><span>"routing"</span><span>: {</span></div></div><div><div><div>54</div></div><div><span>    </span><span>"rules"</span><span>: [</span></div></div><div><div><div>55</div></div><div><span><span>      </span></span><span>{</span></div></div><div><div><div>56</div></div><div><span>        </span><span>"type"</span><span>: </span><span>"field"</span><span>,</span></div></div><div><div><div>57</div></div><div><span>        </span><span>"inboundTag"</span><span>: [</span><span>"tpc-socks-in"</span><span>],</span></div></div><div><div><div>58</div></div><div><span>        </span><span>"outboundTag"</span><span>: </span><span>"warp-proxy"</span></div></div><div><div><div>59</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>60</div></div><div><span><span>      </span></span><span>{</span></div></div><div><div><div>61</div></div><div><span>        </span><span>"type"</span><span>: </span><span>"field"</span><span>,</span></div></div><div><div><div>62</div></div><div><span>        </span><span>"inboundTag"</span><span>: [</span><span>"ria-socks-in"</span><span>],</span></div></div><div><div><div>63</div></div><div><span>        </span><span>"outboundTag"</span><span>: </span><span>"freedomout"</span></div></div><div><div><div>64</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>65</div></div><div><span><span>    </span></span><span>],</span></div></div><div><div><div>66</div></div><div><span>     </span><span>"strategy"</span><span>: </span><span>"rules"</span></div></div><div><div><div>67</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>68</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>设置完之后开放对应的端口，然后重启服务：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>systemctl</span><span> </span><span>restart</span><span> </span><span>xray</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>2. Cloudflare WARP (ZeroTrust)<a href="#2-cloudflare-warp-zerotrust"><span>#</span></a></h2><section><h3>1. 安装WARP<a href="#1-安装warp"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>-fsSL</span><span> </span><span>https://pkg.cloudflareclient.com/pubkey.gpg</span><span> | </span><span>sudo</span><span> </span><span>gpg</span><span> </span><span>--yes</span><span> </span><span>--dearmor</span><span> </span><span>--output</span><span> </span><span>/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vim</span><span> </span><span>/etc/apt/sources.list.d/cloudflare-client.list</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>将bookworm改为你对应的系统的代号，此处使用Debian 12举例</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>deb [arch=amd64 signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://packages.cloudflare.com/cloudflared/ bookworm main</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>update</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>cloudflare-warp</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>2. 创建新用户<a href="#2-创建新用户"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>adduser</span><span> </span><span>username</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>usermod</span><span> </span><span>-aG</span><span> </span><span>sudo</span><span> </span><span>username</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>3. 注册组织<a href="#3-注册组织"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>-u</span><span> </span><span>username</span><span> </span><span>warp-cli</span><span> </span><span>registration</span><span> </span><span>new</span><span> </span><span>YOUR_TEAM_NAME</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>-u</span><span> </span><span>username</span><span> </span><span>warp-cli</span><span> </span><span>registration</span><span> </span><span>token</span><span> </span><span>"your access token"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>4. 连接WARP<a href="#4-连接warp"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>warp-cli</span><span> </span><span>connect</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/mqam/</id>
      <title type="text">QAM在AWGN信道中的理论BER计算</title>
      <published>2025-03-02T00:00:00.000Z</published>
      <updated>2025-03-02T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/mqam/"/>
      <summary type="text">系统性推导4-QAM和16-QAM的误码率表达式</summary>
      <content type="html"><![CDATA[<section><h2>引言<a href="#引言"><span>#</span></a></h2><p>正交幅度调制（QAM）作为现代数字通信的核心技术，通过<strong>幅度和相位联合调制</strong>实现了高频谱效率传输。从Wi-Fi到5G，从光纤通信到卫星链路，QAM技术始终扮演着关键角色。误码率（BER）作为衡量通信系统可靠性的核心指标，其理论计算方法对系统设计具有重要指导意义。本文将系统性推导<strong>4QAM、16QAM</strong>的BER表达式。</p></section>
<section><h2>4-QAM<a href="#4-qam"><span>#</span></a></h2><section><h3>1. 信号能量<a href="#1-信号能量"><span>#</span></a></h3><p>在一个4-QAM的星座图中，以A点举例。</p><span><span><span>SA=E+jES_A = \sqrt{E} + j\sqrt{E}</span><span><span><span></span><span><span>S</span><span><span><span><span><span><span></span><span><span>A</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>j</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span><span><span>Es=(E)2+(E)2=2EE_s = (\sqrt{E})^2 + (\sqrt{E})^2 = 2E</span><span><span><span></span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>(</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span>)</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>(</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span>)</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>2</span><span>E</span></span></span></span></span><p>其中，<span><span>E\sqrt{E}</span><span><span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span> 是 <span><span>II</span><span><span><span></span><span>I</span></span></span></span> 和 <span><span>QQ</span><span><span><span></span><span>Q</span></span></span></span> 两个维度的各自的幅度，<span><span>EE</span><span><span><span></span><span>E</span></span></span></span> 是每个维度的能量，每个符号在两个幅度上的能量之和是 <span><span>2E2E</span><span><span><span></span><span>2</span><span>E</span></span></span></span>。</p><p>因为是4-QAM，每个符号携带的比特数为 <span><span>log⁡2(M)=2\log_2(M) = 2</span><span><span><span></span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>M</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>2</span></span></span></span>，因此：</p><span><span><span>Eb=Eslog⁡2(M)=Es2=EE_b = \frac{E_s}{\log_2(M)} = \frac{E_s}{2} = E</span><span><span><span></span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>M</span><span>)</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>E</span></span></span></span></span><p></p><figure><img alt="image.png" loading="lazy" width="2195" height="1364" src="/_astro/1740880820227_image.CTh3SGbR_Z1SoqU7.webp" /><figcaption>image.png</figcaption></figure><p></p></section><section><h3>2. AWGN信道<a href="#2-awgn信道"><span>#</span></a></h3><p>在AWGN信道中，接收到的信号 <span><span>rr</span><span><span><span></span><span>r</span></span></span></span> 可以表示为：</p><span><span><span>r=s+nr = s + n</span><span><span><span></span><span>r</span><span></span><span>=</span><span></span></span><span><span></span><span>s</span><span></span><span>+</span><span></span></span><span><span></span><span>n</span></span></span></span></span><p>其中 <span><span>ss</span><span><span><span></span><span>s</span></span></span></span> 是发送的信号，<span><span>nn</span><span><span><span></span><span>n</span></span></span></span> 是噪声，为复高斯随机变量，其实部 <span><span>nIn_I</span><span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 与虚部 <span><span>nQn_Q</span><span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 相互独立，每个正交的分量都服从均值为0，方差 <span><span>σ2=N02\sigma^2 = \frac{N_0}{2}</span><span><span><span></span><span><span>σ</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>2</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span> 的分布，其中整个复信号的方差为 <span><span>N0N_0</span><span><span><span></span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>。</p></section><section><h3>3. 判决<a href="#3-判决"><span>#</span></a></h3><p>在接收端，采用最小距离判决规则，即选择与接收信号 <span><span>rr</span><span><span><span></span><span>r</span></span></span></span>（也就是A点）欧氏距离最小的符号点。由于4-QAM符号点是对称的，判决区域可以用坐标轴划分：</p><ul>
<li><span><span>II</span><span><span><span></span><span>I</span></span></span></span> 分量：如果 <span><span>rI&gt;0r_I &gt; 0</span><span><span><span></span><span><span>r</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&gt;</span><span></span></span><span><span></span><span>0</span></span></span></span>，判定 <span><span>sI=Es_I = \sqrt{E}</span><span><span><span></span><span><span>s</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span>，否则 <span><span>sI=−Es_I = -\sqrt{E}</span><span><span><span></span><span><span>s</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>−</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span>。</li>
<li><span><span>QQ</span><span><span><span></span><span>Q</span></span></span></span> 分量：如果 <span><span>rQ&gt;0r_Q &gt; 0</span><span><span><span></span><span><span>r</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&gt;</span><span></span></span><span><span></span><span>0</span></span></span></span>，判定 <span><span>sQ=Es_Q = \sqrt{E}</span><span><span><span></span><span><span>s</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span>，否则 <span><span>sQ=−Es_Q = -\sqrt{E}</span><span><span><span></span><span><span>s</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>−</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span>。</li>
</ul><p><span><span>II</span><span><span><span></span><span>I</span></span></span></span> 和 <span><span>QQ</span><span><span><span></span><span>Q</span></span></span></span> 的判决是相互独立的。</p></section><section><h3>4. 计算BER<a href="#4-计算ber"><span>#</span></a></h3><p>噪声 <span><span>nIn_I</span><span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 和 <span><span>nQn_Q</span><span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 服从高斯分布：</p><span><span><span>nI∼N(0,N02),nQ∼N(0,N02)n_I \sim \mathcal{N} \left(0, \frac{N_0}{2}\right), \quad n_Q \sim \mathcal{N} \left(0, \frac{N_0}{2}\right)</span><span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>∼</span><span></span></span><span><span></span><span>N</span><span></span><span><span><span>(</span></span><span>0</span><span>,</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>,</span><span></span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>∼</span><span></span></span><span><span></span><span>N</span><span></span><span><span><span>(</span></span><span>0</span><span>,</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><p>Q函数的定义为：</p><span><span><span>Q(x)=12π∫x∞e−t22dtQ(x) = \frac{1}{\sqrt{2 \pi}} \int_{x}^{\infty} e^{- \frac{t^2}{2}}dt</span><span><span><span></span><span>Q</span><span>(</span><span>x</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span><span><span><span><span></span><span><span>2</span><span>π</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span><span>∫</span><span><span><span><span><span><span></span><span><span><span>x</span></span></span></span><span><span></span><span><span><span>∞</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>−</span><span><span></span><span><span><span><span><span><span></span><span><span><span>2</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span>t</span><span><span><span><span><span><span></span><span>2</span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></span></span></span></span></span><span>d</span><span>t</span></span></span></span></span><p>对于随机变量 <span><span>X∼N(μ,σ2)X \sim \mathcal{N} (\mu , \sigma^2)</span><span><span><span></span><span>X</span><span></span><span>∼</span><span></span></span><span><span></span><span>N</span><span>(</span><span>μ</span><span>,</span><span></span><span><span>σ</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span>)</span></span></span></span>，有：</p><span><span><span>P(X&lt;a)=Q(μ−aσ)P(X &lt; a) = Q\left(\frac{\mu - a}{\sigma}\right)</span><span><span><span></span><span>P</span><span>(</span><span>X</span><span></span><span>&lt;</span><span></span></span><span><span></span><span>a</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span>μ</span><span></span><span>−</span><span></span><span>a</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><span><span><span>P(X&gt;a)=Q(a−μσ)P(X &gt; a) = Q\left(\frac{a - \mu}{\sigma}\right)</span><span><span><span></span><span>P</span><span>(</span><span>X</span><span></span><span>&gt;</span><span></span></span><span><span></span><span>a</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span>a</span><span></span><span>−</span><span></span><span>μ</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><p>以A点举例，<span><span>s=(E,E)s = (\sqrt{E}, \sqrt{E})</span><span><span><span></span><span>s</span><span></span><span>=</span><span></span></span><span><span></span><span>(</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>,</span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span></span></span></span>。在接收端，从I分量的角度，计算A落在错误的区域 <span><span>rI&lt;0r_I &lt; 0</span><span><span><span></span><span><span>r</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>0</span></span></span></span> 的概率：</p><span><span><span>r=E+nIr = \sqrt{E} + n_I</span><span><span><span></span><span>r</span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span><span><span>P(rI&lt;0)=P(E+nI&lt;0)=P(nI&lt;−E)=Q(Eσ)P(r_I &lt; 0) = P(\sqrt{E} + n_I &lt; 0) = P(n_I &lt; - \sqrt{E}) = Q\left(\frac{\sqrt{E}}{\sigma}\right)</span><span><span><span></span><span>P</span><span>(</span><span><span>r</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>0</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>0</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>−</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><p>则落在I分量上正确的概率为 <span><span>1−Q(Eσ)1 - Q(\frac{\sqrt{E}}{\sigma})</span><span><span><span></span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span>Q</span><span>(</span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span></span></span></span>，同时在两个分量上正确的概率为：</p><span><span><span>[1−Q(Eσ)]2\left[1 - Q\left(\frac{\sqrt{E}}{\sigma}\right)\right]^2</span><span><span><span></span><span><span><span><span>[</span></span><span>1</span><span></span><span>−</span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span>]</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></span><p>在两个分量上出错的概率（符号错误率）为：</p><span><span><span>Pser=1−[1−Q(Eσ)]2=2Q(Eσ)−Q(Eσ)2P_{ser} = 1 - \left[1 - Q\left(\frac{\sqrt{E}}{\sigma}\right)\right]^2 = 2Q\left(\frac{\sqrt{E}}{\sigma}\right) - Q\left(\frac{\sqrt{E}}{\sigma}\right)^2</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span><span><span><span>[</span></span><span>1</span><span></span><span>−</span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span>]</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>2</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>−</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></span><p>代入 <span><span>σ=N0/2\sigma = \sqrt{N_0/2}</span><span><span><span></span><span>σ</span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>/2</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span> 和 <span><span>E=EbE = E_b</span><span><span><span></span><span>E</span><span></span><span>=</span><span></span></span><span><span></span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>：</p><span><span><span>Pser=2Q(EsN0)−Q(EsN0)2P_{ser} = 2Q\left(\sqrt{\frac{E_s}{N_0}}\right) - Q\left(\sqrt{\frac{E_s}{N_0}}\right)^2</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>2</span><span>Q</span><span></span><span><span><span>(</span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span>)</span></span></span><span></span><span>−</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span><span>(</span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></span><p>当 <span><span>EbN0≫1\frac{E_b}{N_0} \gg 1</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>≫</span><span></span></span><span><span></span><span>1</span></span></span></span> 时，可以忽略掉高阶项 <span><span>Q(⋅)2Q(\cdot)^2</span><span><span><span></span><span>Q</span><span>(</span><span>⋅</span><span><span>)</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span>：</p><span><span><span>Pser≈2Q(EsN0)P_{ser} \approx 2Q\left(\sqrt{\frac{E_s}{N_0}}\right)</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>≈</span><span></span></span><span><span></span><span>2</span><span>Q</span><span></span><span><span><span>(</span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span>)</span></span></span></span></span></span></span><span><span><span>BER≈PserBits per Symbol=Q(EsN0)=Q(2EbN0)BER \approx \frac{P_{ser}}{\text{Bits per Symbol}} = Q\left(\sqrt{\frac{E_s}{N_0}}\right) = Q\left(\sqrt{\frac{2E_b}{N_0}}\right)</span><span><span><span></span><span>B</span><span>E</span><span>R</span><span></span><span>≈</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>Bits per Symbol</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span>)</span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>2</span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span>)</span></span></span></span></span></span></span></section></section>
<section><h2>16-QAM<a href="#16-qam"><span>#</span></a></h2><p></p><figure><img alt="image.png" loading="lazy" width="1410" height="916" src="/_astro/1740897268309_image.BWP36SMG_hWxtz.webp" /><figcaption>image.png</figcaption></figure><p></p><section><h3>1. 信号能量<a href="#1-信号能量-1"><span>#</span></a></h3><p>在一个16-QAM的星座图中，有三种类型的点：角点，边缘点，内点。</p><p>其中：</p><ul>
<li>角点：J、G、P、M</li>
<li>边缘点：I、H、E、F、O、N、K、L</li>
<li>内点：A、B、C、D</li>
</ul><p>本文的角点、边缘点、内点分别使用 <span><span>P:(3E,−3E)P:(3 \sqrt{E}, -3 \sqrt{E})</span><span><span><span></span><span>P</span><span></span><span>:</span><span></span></span><span><span></span><span>(</span><span>3</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>,</span><span></span><span>−</span><span>3</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span></span></span></span>、<span><span>H:(E,3E)H:(\sqrt{E}, 3 \sqrt{E})</span><span><span><span></span><span>H</span><span></span><span>:</span><span></span></span><span><span></span><span>(</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>,</span><span></span><span>3</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span></span></span></span>、<span><span>A:(E,E)A:(\sqrt{E}, \sqrt{E})</span><span><span><span></span><span>A</span><span></span><span>:</span><span></span></span><span><span></span><span>(</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>,</span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span></span></span></span> 来举例。</p><span><span><span>SA=E+jES_A = \sqrt{E} + j\sqrt{E}</span><span><span><span></span><span><span>S</span><span><span><span><span><span><span></span><span><span>A</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>j</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span><span><span>SH=E+j3ES_H = \sqrt{E} + j3\sqrt{E}</span><span><span><span></span><span><span>S</span><span><span><span><span><span><span></span><span><span>H</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>j</span><span>3</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span><span><span>SP=3E−j3ES_P = 3\sqrt{E} - j3\sqrt{E}</span><span><span><span></span><span><span>S</span><span><span><span><span><span><span></span><span><span>P</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>3</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>−</span><span></span></span><span><span></span><span>j</span><span>3</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><p>其中，<span><span>E\sqrt{E}</span><span><span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span> 是 <span><span>II</span><span><span><span></span><span>I</span></span></span></span> 和 <span><span>QQ</span><span><span><span></span><span>Q</span></span></span></span> 两个维度的各自的幅度，<span><span>EE</span><span><span><span></span><span>E</span></span></span></span> 是每个维度的能量。</p><p>因为是16-QAM，每个符号携带的比特数为 <span><span>log⁡2(M)=4\log_2(M) = 4</span><span><span><span></span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>M</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>4</span></span></span></span>，因此：</p><span><span><span>Eb=Eslog⁡2(M)=Es4E_b = \frac{E_s}{\log_2(M)} = \frac{E_s}{4}</span><span><span><span></span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>M</span><span>)</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>4</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></span><p>其中16个点的平均符号能量 <span><span>EsE_s</span><span><span><span></span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 为：</p><span><span><span>Es=18E⋅4+10E⋅8+2E⋅416=10EE_s = \frac{18E \cdot 4 + 10E \cdot 8 + 2E \cdot 4}{16} = 10E</span><span><span><span></span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>16</span></span></span><span><span></span><span></span></span><span><span></span><span><span>18</span><span>E</span><span></span><span>⋅</span><span></span><span>4</span><span></span><span>+</span><span></span><span>10</span><span>E</span><span></span><span>⋅</span><span></span><span>8</span><span></span><span>+</span><span></span><span>2</span><span>E</span><span></span><span>⋅</span><span></span><span>4</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>10</span><span>E</span></span></span></span></span><span><span><span>E=Es10=4Eb10=25EbE = \frac{E_s}{10} = \frac{4E_b}{10} = \frac{2}{5} E_b</span><span><span><span></span><span>E</span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>10</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>10</span></span></span><span><span></span><span></span></span><span><span></span><span><span>4</span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>5</span></span></span><span><span></span><span></span></span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span></section><section><h3>2. AWGN信道<a href="#2-awgn信道-1"><span>#</span></a></h3><p>在AWGN信道中，接收到的信号 <span><span>rr</span><span><span><span></span><span>r</span></span></span></span> 可以表示为：</p><span><span><span>r=s+nr = s + n</span><span><span><span></span><span>r</span><span></span><span>=</span><span></span></span><span><span></span><span>s</span><span></span><span>+</span><span></span></span><span><span></span><span>n</span></span></span></span></span><p>其中 <span><span>ss</span><span><span><span></span><span>s</span></span></span></span> 是发送的信号，<span><span>nn</span><span><span><span></span><span>n</span></span></span></span> 是噪声，为复高斯随机变量，其实部 <span><span>nIn_I</span><span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 与虚部 <span><span>nQn_Q</span><span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 相互独立，每个正交的分量都服从均值为0，方差 <span><span>σ2=N02\sigma^2 = \frac{N_0}{2}</span><span><span><span></span><span><span>σ</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>2</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span> 的分布，其中整个复信号的方差为 <span><span>N0N_0</span><span><span><span></span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>。</p></section><section><h3>3. 判决<a href="#3-判决-1"><span>#</span></a></h3><section><h4>3.1 内点<a href="#31-内点"><span>#</span></a></h4><p>以A点为例，需要满足在 <span><span>I:(0,2E)I:(0, 2\sqrt{E})</span><span><span><span></span><span>I</span><span></span><span>:</span><span></span></span><span><span></span><span>(</span><span>0</span><span>,</span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span></span></span></span>，<span><span>Q:(0,2E)Q:(0, 2\sqrt{E})</span><span><span><span></span><span>Q</span><span></span><span>:</span><span></span></span><span><span></span><span>(</span><span>0</span><span>,</span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span></span></span></span> 的范围内，即判定为正确的信号。</p><p>在接收端，从I分量的角度，计算A落在错误的区域 <span><span>rI&lt;0r_I &lt; 0</span><span><span><span></span><span><span>r</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>0</span></span></span></span> 或 <span><span>rI&gt;2Er_I &gt; 2\sqrt{E}</span><span><span><span></span><span><span>r</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&gt;</span><span></span></span><span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span> 的概率：</p><span><span><span>r=E+nIr = \sqrt{E} + n_I</span><span><span><span></span><span>r</span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span><span><span>P(rI&lt;0)=P(E+nI&lt;0)=P(nI&lt;−E)=Q(Eσ)P(r_I &lt; 0) = P(\sqrt{E} + n_I &lt; 0) = P(n_I &lt; - \sqrt{E}) = Q\left(\frac{\sqrt{E}}{\sigma}\right)</span><span><span><span></span><span>P</span><span>(</span><span><span>r</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>0</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>0</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>−</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><span><span><span>P(rI&gt;2E)=P(E+nI&gt;2E)=P(nI&gt;E)=Q(Eσ)P(r_I &gt; 2\sqrt{E}) = P(\sqrt{E} + n_I &gt; 2\sqrt{E}) = P(n_I &gt; \sqrt{E}) = Q\left(\frac{\sqrt{E}}{\sigma}\right)</span><span><span><span></span><span>P</span><span>(</span><span><span>r</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&gt;</span><span></span></span><span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&gt;</span><span></span></span><span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&gt;</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><p>在I分量上出错的概率为：</p><span><span><span>Q(Eσ)+Q(Eσ)=2Q(Eσ)Q\left(\frac{\sqrt{E}}{\sigma}\right) + Q\left(\frac{\sqrt{E}}{\sigma}\right) = 2Q\left(\frac{\sqrt{E}}{\sigma}\right)</span><span><span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>2</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><p>则落在I分量上正确的概率为 <span><span>1−2Q(Eσ)1 - 2Q(\frac{\sqrt{E}}{\sigma})</span><span><span><span></span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span>2</span><span>Q</span><span>(</span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span></span></span></span>。在这个例子中，I分量和Q分量相互独立，概率相同，同时在两个分量上正确的概率为：</p><span><span><span>[1−2Q(Eσ)]2\left[1 - 2Q\left(\frac{\sqrt{E}}{\sigma}\right)\right]^2</span><span><span><span></span><span><span><span><span>[</span></span><span>1</span><span></span><span>−</span><span></span><span>2</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span>]</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></span><p>在两个分量上出错的概率为：</p><span><span><span>Pser1=1−[1−2Q(Eσ)]2=4Q(Eσ)−4Q(Eσ)2P_{ser1} = 1 - \left[1 - 2Q\left(\frac{\sqrt{E}}{\sigma}\right)\right]^2 = 4Q\left(\frac{\sqrt{E}}{\sigma}\right) - 4Q\left(\frac{\sqrt{E}}{\sigma}\right)^2</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span><span><span><span>[</span></span><span>1</span><span></span><span>−</span><span></span><span>2</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span>]</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>4</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>−</span><span></span></span><span><span></span><span>4</span><span>Q</span><span></span><span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></span></section><section><h4>3.2 边缘点<a href="#32-边缘点"><span>#</span></a></h4><p>以H点为例，需要满足在 <span><span>I:(0,2E)I:(0, 2\sqrt{E})</span><span><span><span></span><span>I</span><span></span><span>:</span><span></span></span><span><span></span><span>(</span><span>0</span><span>,</span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span></span></span></span>，<span><span>Q:(2E,+∞)Q:(2\sqrt{E}, +\infty)</span><span><span><span></span><span>Q</span><span></span><span>:</span><span></span></span><span><span></span><span>(</span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>,</span><span></span><span>+</span><span>∞</span><span>)</span></span></span></span> 的范围内，即判定为正确的信号。</p><p>在接收端，从I分量的角度，计算H落在错误的区域 <span><span>rI&lt;0r_I &lt; 0</span><span><span><span></span><span><span>r</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>0</span></span></span></span> 或 <span><span>rI&gt;2Er_I &gt; 2\sqrt{E}</span><span><span><span></span><span><span>r</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&gt;</span><span></span></span><span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span> 的概率：</p><p>同内点的情况，在I分量上出错的概率为 <span><span>2Q(Eσ)2Q(\frac{\sqrt{E}}{\sigma})</span><span><span><span></span><span>2</span><span>Q</span><span>(</span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span></span></span></span>。
则落在I分量上正确的概率为 <span><span>1−2Q(Eσ)1 - 2Q(\frac{\sqrt{E}}{\sigma})</span><span><span><span></span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span>2</span><span>Q</span><span>(</span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span></span></span></span>。</p><p>从Q分量的角度看，计算H落在错误的区域 <span><span>rQ&lt;2Er_Q &lt; 2\sqrt{E}</span><span><span><span></span><span><span>r</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span> 的概率：</p><span><span><span>r=3E+nQr = 3\sqrt{E} + n_Q</span><span><span><span></span><span>r</span><span></span><span>=</span><span></span></span><span><span></span><span>3</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span><span><span>P(rQ&lt;2E)=P(3E+nQ&lt;2E)=P(nQ&lt;−E)=Q(Eσ)P(r_Q &lt; 2\sqrt{E}) = P(3\sqrt{E} + n_Q &lt; 2\sqrt{E}) = P(n_Q &lt; - \sqrt{E}) = Q\left(\frac{\sqrt{E}}{\sigma}\right)</span><span><span><span></span><span>P</span><span>(</span><span><span>r</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span>3</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span><span>n</span><span><span><span><span><span><span></span><span><span>Q</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>−</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><p>则落在Q分量上正确的概率为 <span><span>1−Q(Eσ)1 - Q(\frac{\sqrt{E}}{\sigma})</span><span><span><span></span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span>Q</span><span>(</span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span></span></span></span>。</p><p>同时在两个分量上正确的概率为：</p><span><span><span>Pcorrect=[1−2Q(Eσ)]⋅[1−Q(Eσ)]P_{correct} = \left[1 - 2Q\left(\frac{\sqrt{E}}{\sigma}\right)\right] \cdot \left[1 - Q\left(\frac{\sqrt{E}}{\sigma}\right)\right]</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>cor</span><span>r</span><span>ec</span><span>t</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>[</span></span><span>1</span><span></span><span>−</span><span></span><span>2</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span>]</span></span></span><span></span><span>⋅</span><span></span></span><span><span></span><span><span><span>[</span></span><span>1</span><span></span><span>−</span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span>]</span></span></span></span></span></span></span><p>在两个分量上出错的概率为：</p><span><span><span>Pser2=1−Pcorrect=3Q(Eσ)−2Q(Eσ)2P_{ser2} = 1 - P_{correct} = 3Q\left(\frac{\sqrt{E}}{\sigma}\right) - 2Q\left(\frac{\sqrt{E}}{\sigma}\right)^2</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span><span>2</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>cor</span><span>r</span><span>ec</span><span>t</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>3</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>−</span><span></span></span><span><span></span><span>2</span><span>Q</span><span></span><span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></span></section><section><h4>3.3 角点<a href="#33-角点"><span>#</span></a></h4><p>以P点为例，需要满足在 <span><span>I:(2E,+∞)I:(2\sqrt{E}, +\infty)</span><span><span><span></span><span>I</span><span></span><span>:</span><span></span></span><span><span></span><span>(</span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>,</span><span></span><span>+</span><span>∞</span><span>)</span></span></span></span>，<span><span>Q:(−2E,−∞)Q:(- 2\sqrt{E}, -\infty)</span><span><span><span></span><span>Q</span><span></span><span>:</span><span></span></span><span><span></span><span>(</span><span>−</span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>,</span><span></span><span>−</span><span>∞</span><span>)</span></span></span></span> 的范围内，即判定为正确的信号。</p><p>在接收端，从I分量的角度，计算P落在错误的区域 <span><span>rI&lt;2Er_I &lt; 2\sqrt{E}</span><span><span><span></span><span><span>r</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span> 的概率：</p><span><span><span>r=3E+nIr = 3\sqrt{E} + n_I</span><span><span><span></span><span>r</span><span></span><span>=</span><span></span></span><span><span></span><span>3</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span><span><span>P(rI&lt;2E)=P(3E+nI&lt;2E)=P(nI&lt;−E)=Q(Eσ)P(r_I &lt; 2\sqrt{E}) = P(3\sqrt{E} + n_I &lt; 2\sqrt{E}) = P(n_I &lt; - \sqrt{E}) = Q\left(\frac{\sqrt{E}}{\sigma}\right)</span><span><span><span></span><span>P</span><span>(</span><span><span>r</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span>3</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>2</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span><span>n</span><span><span><span><span><span><span></span><span><span>I</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>&lt;</span><span></span></span><span><span></span><span>−</span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><p>则落在I分量上正确的概率为 <span><span>1−Q(Eσ)1 - Q(\frac{\sqrt{E}}{\sigma})</span><span><span><span></span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span>Q</span><span>(</span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span></span></span></span>。在这个例子中，I分量和Q分量相互独立，概率相同，同时在两个分量上正确的概率为：</p><span><span><span>[1−Q(Eσ)]2\left[1 - Q\left(\frac{\sqrt{E}}{\sigma}\right)\right]^2</span><span><span><span></span><span><span><span><span>[</span></span><span>1</span><span></span><span>−</span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span>]</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></span><p>在两个分量上出错的概率为：</p><span><span><span>Pser3=1−[1−Q(Eσ)]2=2Q(Eσ)−Q(Eσ)2P_{ser3} = 1 - \left[1 - Q\left(\frac{\sqrt{E}}{\sigma}\right)\right]^2 = 2Q\left(\frac{\sqrt{E}}{\sigma}\right) - Q\left(\frac{\sqrt{E}}{\sigma}\right)^2</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span><span>3</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span><span><span><span>[</span></span><span>1</span><span></span><span>−</span><span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span>]</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>2</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>−</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></span></section></section><section><h3>4. 计算BER<a href="#4-计算ber-1"><span>#</span></a></h3><p>三类符号点出错的概率分别为：</p><ul>
<li>内点：<span><span>Pser1=4Q(Eσ)−4Q(Eσ)2P_{ser1} = 4Q\left(\frac{\sqrt{E}}{\sigma}\right) - 4Q\left(\frac{\sqrt{E}}{\sigma}\right)^2</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>4</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>−</span><span></span></span><span><span></span><span>4</span><span>Q</span><span></span><span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></li>
<li>边缘点：<span><span>Pser2=3Q(Eσ)−2Q(Eσ)2P_{ser2} = 3Q\left(\frac{\sqrt{E}}{\sigma}\right) - 2Q\left(\frac{\sqrt{E}}{\sigma}\right)^2</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span><span>2</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>3</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>−</span><span></span></span><span><span></span><span>2</span><span>Q</span><span></span><span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></li>
<li>角点：<span><span>Pser3=2Q(Eσ)−Q(Eσ)2P_{ser3} = 2Q\left(\frac{\sqrt{E}}{\sigma}\right) - Q\left(\frac{\sqrt{E}}{\sigma}\right)^2</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span><span>3</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>2</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>−</span><span></span></span><span><span></span><span>Q</span><span></span><span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>σ</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></li>
</ul><p>总的符号错误概率为：</p><span><span><span>Pser=4⋅Pser1+8⋅Pser2+4⋅Pser316=3Q(Eσ)−94Q(Eσ)2P_{ser} = \frac{4 \cdot P_{ser1} + 8 \cdot P_{ser2} + 4 \cdot P_{ser3}}{16} = 3 Q\left(\frac{\sqrt{E}}{\sigma}\right) - \frac{9}{4} Q\left(\frac{\sqrt{E}}{\sigma}\right)^2</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>16</span></span></span><span><span></span><span></span></span><span><span></span><span><span>4</span><span></span><span>⋅</span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span><span>8</span><span></span><span>⋅</span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span><span>2</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span><span>4</span><span></span><span>⋅</span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span><span>3</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>3</span><span>Q</span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>−</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>4</span></span></span><span><span></span><span></span></span><span><span></span><span><span>9</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>Q</span><span></span><span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></span><p>根据 <span><span>σ=N02\sigma = \sqrt{\frac{N_0}{2}}</span><span><span><span></span><span>σ</span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>2</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span> 和 <span><span>E=25EbE = \frac{2}{5}E_b</span><span><span><span></span><span>E</span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>5</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>2</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>：</p><span><span><span>Eσ=EN0/2=2EN0=2⋅25EbN0=45EbN0\frac{\sqrt{E}}{\sigma} = \sqrt{\frac{E}{N_0/2}} = \sqrt{\frac{2E}{N_0}} = \sqrt{\frac{2 \cdot \frac{2}{5}E_b}{N_0}} = \sqrt{\frac{4}{5} \frac{E_b}{N_0}}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>σ</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span><span><span><span></span><span><span>E</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>/2</span></span></span><span><span></span><span></span></span><span><span></span><span><span>E</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>2</span><span>E</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>2</span><span></span><span>⋅</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>5</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>2</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span>5</span></span></span><span><span></span><span></span></span><span><span></span><span><span>4</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><p>代入得：</p><span><span><span>Pser=3Q(45⋅EbN0)−94Q(45⋅EbN0)2P_{ser} = 3 Q\left(\sqrt{\frac{4}{5} \cdot \frac{E_b}{N_0}}\right) - \frac{9}{4} Q\left(\sqrt{\frac{4}{5} \cdot \frac{E_b}{N_0}}\right)^2</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>3</span><span>Q</span><span></span><span><span><span>(</span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span>5</span></span></span><span><span></span><span></span></span><span><span></span><span><span>4</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>⋅</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span>)</span></span></span><span></span><span>−</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>4</span></span></span><span><span></span><span></span></span><span><span></span><span><span>9</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>Q</span><span></span><span><span><span><span>(</span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span>5</span></span></span><span><span></span><span></span></span><span><span></span><span><span>4</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>⋅</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></span><p>当 <span><span>EbN0≫1\frac{E_b}{N_0} \gg 1</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>≫</span><span></span></span><span><span></span><span>1</span></span></span></span> 时，可以忽略掉高阶项：</p><span><span><span>Pser≈3Q(45⋅EbN0)P_{ser} \approx 3 Q\left(\sqrt{\frac{4}{5} \cdot \frac{E_b}{N_0}}\right)</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>≈</span><span></span></span><span><span></span><span>3</span><span>Q</span><span></span><span><span><span>(</span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span>5</span></span></span><span><span></span><span></span></span><span><span></span><span><span>4</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>⋅</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span>)</span></span></span></span></span></span></span><span><span><span>BER≈PserBits per Symbol=34Q(45⋅EbN0)BER \approx \frac{P_{ser}}{\text{Bits per Symbol}} = \frac{3}{4} Q\left(\sqrt{\frac{4}{5} \cdot \frac{E_b}{N_0}}\right)</span><span><span><span></span><span>B</span><span>E</span><span>R</span><span></span><span>≈</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>Bits per Symbol</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>P</span><span><span><span><span><span><span></span><span><span><span>ser</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>4</span></span></span><span><span></span><span></span></span><span><span></span><span><span>3</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>Q</span><span></span><span><span><span>(</span></span><span><span><span><span><span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span>5</span></span></span><span><span></span><span></span></span><span><span></span><span><span>4</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>⋅</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span>)</span></span></span></span></span></span></span></section></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/snr-eb-n0/</id>
      <title type="text">SNR与Eb/N0的关系</title>
      <published>2025-02-27T00:00:00.000Z</published>
      <updated>2025-02-27T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/snr-eb-n0/"/>
      <summary type="text">信噪比与比特能量噪声功率谱密度比的转换推导</summary>
      <content type="html"><![CDATA[<section><h2>引言<a href="#引言"><span>#</span></a></h2><p>在无线通信和信道编码领域，信噪比（SNR）和比特能量与噪声功率谱密度比（Eb/N0）是两个至关重要的概念。它们在评估通信系统的性能时经常被提及，但很多人对它们的关系不甚了解。本文将依次介绍 SNR 和 Eb/N0，并推导出它们之间的转换公式。</p></section>
<section><h2>1. 信噪比（SNR）<a href="#1-信噪比snr"><span>#</span></a></h2><p>信噪比（Signal-to-Noise Ratio, SNR）表示信号功率与噪声功率的比值，通常用分贝（dB）表示，其定义如下：</p><span><span><span>SNR=PsPn\text{SNR} = \frac{P_s}{P_n}</span><span><span><span></span><span><span>SNR</span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>P</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>P</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></span><p>其中，<span><span>PsP_s</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 是信号的平均功率，<span><span>PnP_n</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 是噪声的平均功率。</p></section>
<section><h2>2. 比特能量与噪声功率谱密度比（Eb/N0）<a href="#2-比特能量与噪声功率谱密度比ebn0"><span>#</span></a></h2><p>Eb/N0（Energy per Bit to Noise Power Spectral Density Ratio）表示每比特能量与噪声功率谱密度的比值，定义如下：</p><span><span><span>EbN0\frac{E_b}{N_0}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></span><p>其中，<span><span>EbE_b</span><span><span><span></span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 是每个比特的平均能量，<span><span>N0N_0</span><span><span><span></span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 是噪声的功率谱密度。</p></section>
<section><h2>3. 推导<a href="#3-推导"><span>#</span></a></h2><p><span><span>Eb=PsRbE_b = \frac{P_s}{R_b}</span><span><span><span></span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span>P</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span>，在AWGN信道的情况下，<span><span>Pn=N0⋅B=σ2P_n = N_0 \cdot B = \sigma^2</span><span><span><span></span><span><span>P</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>⋅</span><span></span></span><span><span></span><span>B</span><span></span><span>=</span><span></span></span><span><span></span><span><span>σ</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span>。</p><span><span><span>EbN0=Ps/RbPn/B=PsPn⋅BRb=SNR⋅BRb\frac{E_b}{N_0} = \frac{P_s / R_b}{P_n / B} = \frac{P_s}{P_n} \cdot \frac{B}{R_b} = \text{SNR} \cdot \frac{B}{R_b}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>P</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>/</span><span>B</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>P</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>/</span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>P</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>P</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>⋅</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>B</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span>SNR</span></span><span></span><span>⋅</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>B</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></span><p>如果我们转换成dB形式：</p><span><span><span>10log⁡10(EbN0)=10log⁡10(SNR⋅BRb)10\log_{10}\left(\frac{E_b}{N_0}\right) = 10\log_{10}\left(\text{SNR} \cdot \frac{B}{R_b}\right)</span><span><span><span></span><span>10</span><span></span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span><span>10</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>10</span><span></span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span><span>10</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span><span><span>(</span></span><span><span>SNR</span></span><span></span><span>⋅</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>B</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><span><span><span>(EbN0)dB=SNRdB+10log⁡10(BRb)\left(\frac{E_b}{N_0}\right)_{\text{dB}} = \text{SNR}_{\text{dB}} + 10\log_{10}\left(\frac{B}{R_b}\right)</span><span><span><span></span><span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span><span><span>dB</span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>SNR</span></span><span><span><span><span><span><span></span><span><span><span><span>dB</span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>10</span><span></span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span><span>10</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>B</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><p>其中：</p><ul>
<li><span><span>RbB\frac{R_b}{B}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>B</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span>：带宽效率，Spectral Efficiency</li>
<li><span><span>RbR_b</span><span><span><span></span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>：比特率，Bit Rate</li>
<li><span><span>BB</span><span><span><span></span><span>B</span></span></span></span>：带宽，Bandwidth</li>
</ul><p>在 M 阶 QAM（M-QAM）调制下，每个符号可以表示 <span><span>log⁡2(M)\log_2(M)</span><span><span><span></span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>M</span><span>)</span></span></span></span> 个比特，因此符号率 <span><span>RsR_s</span><span><span><span></span><span><span>R</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 为：</p><span><span><span>Rs=Rblog⁡2(M)R_s = \frac{R_b}{\log_2(M)}</span><span><span><span></span><span><span>R</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>M</span><span>)</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></span><p>对于一般的 QAM 调制，所需的带宽 <strong>B</strong> 通常近似为符号率 <span><span>RsR_s</span><span><span><span></span><span><span>R</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>，即：</p><span><span><span>B≈Rs=Rblog⁡2(M)B \approx R_s = \frac{R_b}{\log_2(M)}</span><span><span><span></span><span>B</span><span></span><span>≈</span><span></span></span><span><span></span><span><span>R</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>M</span><span>)</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></span><p>因此，M-QAM的带宽效率可以近似为：</p><span><span><span>k=log⁡2(M)k = \log_2(M)</span><span><span><span></span><span>k</span><span></span><span>=</span><span></span></span><span><span></span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>M</span><span>)</span></span></span></span></span><p>由于 <span><span>BRb≈1k\frac{B}{R_b} \approx \frac{1}{k}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>B</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>≈</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>k</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span>，因此 <span><span>10log⁡10(BRb)=10log⁡10(1k)=−10log⁡10(k)10\log_{10}(\frac{B}{R_b}) = 10\log_{10}(\frac{1}{k}) = -10\log_{10}(k)</span><span><span><span></span><span>10</span><span></span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span><span>10</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span><span></span><span><span><span><span><span><span></span><span><span><span><span>R</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>B</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>10</span><span></span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span><span>10</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span><span></span><span><span><span><span><span><span></span><span><span><span>k</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>−</span><span>10</span><span></span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span><span>10</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>k</span><span>)</span></span></span></span>。</p><p>因此在使用M-QAM调制的时候，<span><span>SNR\text{SNR}</span><span><span><span></span><span><span>SNR</span></span></span></span></span> 和 <span><span>EbN0\frac{E_b}{N_0}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span> 的公式可以近似为：</p><span><span><span>(EbN0)dB=SNRdB−10log⁡10(k)\left(\frac{E_b}{N_0}\right)_{\text{dB}} = \text{SNR}_{\text{dB}} - 10\log_{10}(k)</span><span><span><span></span><span><span><span><span>(</span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>N</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>E</span><span><span><span><span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span><span><span><span><span><span><span></span><span><span><span><span>dB</span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>SNR</span></span><span><span><span><span><span><span></span><span><span><span><span>dB</span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>−</span><span></span></span><span><span></span><span>10</span><span></span><span><span>lo<span>g</span></span><span><span><span><span><span><span></span><span><span><span>10</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>k</span><span>)</span></span></span></span></span></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/owcofdm/</id>
      <title type="text">光通信中的OFDM：ACO-OFDM与DCO-OFDM</title>
      <published>2025-02-24T00:00:00.000Z</published>
      <updated>2025-02-24T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/owcofdm/"/>
      <summary type="text">详解光通信系统中的两种OFDM变体技术</summary>
      <content type="html"><![CDATA[<section><h2>引言<a href="#引言"><span>#</span></a></h2><p>在之前的文章已经简单概述了正交频分复用（OFDM）的基本概念，它通过将数据分成多个并行的子载波传输，显著提高了频谱效率和抗多径干扰能力。然而，在光通信下，普通的OFDM并不能直接适用。为什么呢？因为光通信系统中，光信号的强度必须是非负的，而传统OFDM生成的信号是双极性的（既有正值又有负值）。为了解决这个问题，研究者们开发了两种特殊的OFDM变种：<strong>ACO-OFDM</strong>（非对称裁剪光OFDM）和<strong>DCO-OFDM</strong>（直流偏置光OFDM）。</p><p>光通信系统，尤其是可见光通信（VLC）或光无线通信（OWC），通常使用LED作为发射器，光电二极管作为接收器。这种系统中，信号通过光强度的变化来传递信息，因此信号必须是实数且非负的。然而，传统OFDM信号是复数形式的，需要通过IFFT生成时域信号后，再经过调制才能传输。这些信号天然包含正负值，直接用于光通信会导致信息丢失或失真，另一方面，IM/DD也必须需要实数信号。为了解决这个矛盾，ACO-OFDM和DCO-OFDM应运而生。</p></section>
<section><h2>ACO-OFDM<a href="#aco-ofdm"><span>#</span></a></h2><p>ACO-OFDM（Asymmetrically Clipped Optical OFDM）主要解决了如何在不添加额外偏置的情况下生成非负信号的问题。传统OFDM信号的双极性特性在光通信中是个大麻烦，而ACO-OFDM通过一种“裁剪”策略，既避免了负值，又尽量减少了对信号完整性的影响。</p><p>ACO-OFDM的核心思想是只使用奇数子载波传输数据，并对负值部分进行非对称裁剪。</p><p>其中首先需要解决信号中的虚部的问题。</p><p>在IFFT的数学性质中，如果输入向量 <span><span>X(k)X(k)</span><span><span><span></span><span>X</span><span>(</span><span>k</span><span>)</span></span></span></span> 是任意实数，输出 <span><span>x(n)x(n)</span><span><span><span></span><span>x</span><span>(</span><span>n</span><span>)</span></span></span></span> 通常是复数。但是如果输入满足Hermitian对称性，那么IFFT生成的时域信号 <span><span>x(n)x(n)</span><span><span><span></span><span>x</span><span>(</span><span>n</span><span>)</span></span></span></span> 就会是纯实数，虚部为零。</p><p>对于一个包含 <span><span>NN</span><span><span><span></span><span>N</span></span></span></span> 个子载波的频域向量 <span><span>X(k) (k=0,1,…,N−1)X(k) \ (k = 0, 1, \dots, N-1)</span><span><span><span></span><span>X</span><span>(</span><span>k</span><span>)</span><span> </span><span>(</span><span>k</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span><span>,</span><span></span><span>1</span><span>,</span><span></span><span>…</span><span></span><span>,</span><span></span><span>N</span><span></span><span>−</span><span></span></span><span><span></span><span>1</span><span>)</span></span></span></span>，满足：</p><span><span><span>X(k)=X∗(N−k)X(k) = X^{*}(N-k)</span><span><span><span></span><span>X</span><span>(</span><span>k</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span>X</span><span><span><span><span><span><span></span><span><span><span>∗</span></span></span></span></span></span></span></span></span><span>(</span><span>N</span><span></span><span>−</span><span></span></span><span><span></span><span>k</span><span>)</span></span></span></span></span><p>其中：</p><ul>
<li><span><span>X(k)X(k)</span><span><span><span></span><span>X</span><span>(</span><span>k</span><span>)</span></span></span></span> 是第 <span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 个子载波。</li>
<li><span><span>X∗(N−k)X^{*}(N-k)</span><span><span><span></span><span><span>X</span><span><span><span><span><span><span></span><span><span><span>∗</span></span></span></span></span></span></span></span></span><span>(</span><span>N</span><span></span><span>−</span><span></span></span><span><span></span><span>k</span><span>)</span></span></span></span> 是第 <span><span>N−kN-k</span><span><span><span></span><span>N</span><span></span><span>−</span><span></span></span><span><span></span><span>k</span></span></span></span> 个子载波的复共轭（实部不变，虚部取反）。</li>
<li><span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 和 <span><span>N−kN-k</span><span><span><span></span><span>N</span><span></span><span>−</span><span></span></span><span><span></span><span>k</span></span></span></span> 关于向量中点对称。</li>
<li><span><span>X(0)X(0)</span><span><span><span></span><span>X</span><span>(</span><span>0</span><span>)</span></span></span></span> 必须是实数。</li>
<li>如果 <span><span>NN</span><span><span><span></span><span>N</span></span></span></span> 为偶数，则中间点 <span><span>X(N/2)X(N/2)</span><span><span><span></span><span>X</span><span>(</span><span>N</span><span>/2</span><span>)</span></span></span></span> 也必须是实数。</li>
</ul><p>如果满足以上定义，则IFFT生成的时域信号 <span><span>x(n)x(n)</span><span><span><span></span><span>x</span><span>(</span><span>n</span><span>)</span></span></span></span> 将是纯实数（没有虚部）。</p><p>其次需要解决信号中的实数的负数的问题。</p><p>在ACO-OFDM中，只需要将调制后的QAM符号加载到OFDM的奇数编号的子载波上，而偶数编号的子载波设置为零，就可以让输出的符号满足<strong>反相对称性</strong>。</p><p>即：</p><span><span><span>x(n)=−x(n+N2)x(n) = -x\left(n + \frac{N}{2}\right)</span><span><span><span></span><span>x</span><span>(</span><span>n</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>−</span><span>x</span><span></span><span><span><span>(</span></span><span>n</span><span></span><span>+</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span></span></span><span><span></span><span><span>N</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>)</span></span></span></span></span></span></span><p>例如：<code>1, 2, 3, 4, -1, -2, -3, -4</code>。</p><p>将时域信号中小于零的部分直接裁剪为零，只保留正值部分（<code>1, 2, 3, 4, 0, 0, 0, 0</code>）。这种操作看似会丢失信息，但由于奇数子载波的对称性设计，裁剪产生的噪声只会落在偶数子载波上，而这些子载波本来就不携带数据，因此不影响解调。</p><p>这样就解决了复数的虚部问题，以及实数的负数的问题。</p><p><strong>优点</strong></p><ul>
<li><strong>功率效率高</strong>：由于不需要额外的直流偏置，ACO-OFDM在光功率利用上非常高效，特别适合对发射功率敏感的场景（如低功耗设备）。</li>
<li><strong>简单实现</strong>：裁剪操作简单，接收端只需常规FFT即可恢复数据。</li>
</ul><p><strong>缺点</strong></p><ul>
<li><strong>带宽效率低</strong>：只使用一半子载波，导致频谱利用率比传统OFDM低50%。</li>
<li><strong>数据速率受限</strong>：由于带宽减少，能传输的数据量也相应减少。</li>
</ul></section>
<section><h2>DCO-OFDM<a href="#dco-ofdm"><span>#</span></a></h2><p>DCO-OFDM（DC-biased Optical OFDM）则通过添加直流偏置（DC bias）来解决信号非负性的问题。它的目标是保留OFDM的高带宽效率，同时适配光通信的需求。相比ACO-OFDM，它更注重充分利用所有子载波来提升数据速率。</p><p>和ACO-OFDM一致，DCO-OFDM也使用Hermitian对称的性质确保IFFT的结果全部为实数，在此不再赘述，两者的区别主要在处理实数中的负数。</p><p>**直流偏置（DC Bias）**是指在信号上叠加一个恒定的正值（直流分量），目的是将信号整体“抬高”，确保所有值都变成非负的。它是一个简单的加法操作，不改变信号的形状，只是整体平移。</p><span><span><span>xDCO(n)=x(n)+Bx_{\text{DCO}}(n) = x(n) + B</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span><span>DCO</span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>n</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>x</span><span>(</span><span>n</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>B</span></span></span></span></span><p>相当于在原信号 <span><span>x(n)x(n)</span><span><span><span></span><span>x</span><span>(</span><span>n</span><span>)</span></span></span></span> 上加了一个直流偏置 <span><span>BB</span><span><span><span></span><span>B</span></span></span></span>，这样就可以确保 <span><span>x(n)x(n)</span><span><span><span></span><span>x</span><span>(</span><span>n</span><span>)</span></span></span></span> 都是正值，过程十分简单。在我们不知道信号负值的最小值的时候，可以允许一定程度的裁剪，即使添加偏置后仍然小于0的值我们可以直接设置为0。</p><p><strong>优点</strong></p><ul>
<li>简单直接，保留信号完整形状。</li>
<li>使用所有子载波，带宽效率高。</li>
</ul><p><strong>缺点</strong></p><ul>
<li>添加偏置会消耗额外的功率。</li>
<li>如果偏置不够大，负值没完全消除，会被裁剪，引入失真；偏置太大，又浪费更多功率。</li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/ofdm/</id>
      <title type="text">OFDM 正交频分复用技术概述</title>
      <published>2025-02-23T00:00:00.000Z</published>
      <updated>2025-02-23T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/ofdm/"/>
      <summary type="text">从载波调制到OFDM技术的系统性介绍</summary>
      <content type="html"><![CDATA[<section><h2>引言<a href="#引言"><span>#</span></a></h2><p>在当今的无线通信技术中，从Wi-Fi到5G，从广播电视到卫星通信，OFDM作为一种高效的调制技术得到了广泛的应用。相比传统的单载波传输，OFDM通过将数据分割到多个正交子载波上传输，不仅能够显著提高带宽利用率，还能有效应对多路径干扰等无线信道问题。</p><p>OFDM的魅力在于它简单却强大的核心思想：将一个复杂的高速信号“分而治之”，分成多个低速子信号进行并行传输。这种方式既解决了码间干扰（ISI）的困扰，同时能够高效适应不同的传输环境，为高速稳定的数据传输提供支持。</p><p>本文将从一些基础性的东西出发，逐步解析OFDM的整体流程。</p></section>
<section><h2>1. 载波与信息<a href="#1-载波与信息"><span>#</span></a></h2><p><strong>信号</strong>是用来传递信息的工具。它可以是<strong>模拟信号</strong>（如声音、视频）或<strong>数字信号</strong>（如0和1组成的二进制代码）。信号本身往往处于低频或基带状态，在这种状态下，它无法有效传播到远距离。例如无线通信中，天线的尺寸往往和信号的波长成比例，而波长 <span><span>λ=cf\lambda = \frac{c}{f}</span><span><span><span></span><span>λ</span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>f</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>c</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span> （其中 <span><span>ff</span><span><span><span></span><span>f</span></span></span></span> 是频率，<span><span>cc</span><span><span><span></span><span>c</span></span></span></span> 是光速），这就意味着低频信号的波长非常长，需要极大尺寸的天线，在实际应用中存在巨大的困难。</p><p><strong>载波</strong>是一种较高频率的周期性波形，它本身是没有信息的，但可以通过调制改变其属性（如幅度、频率或相位），从而“携带”信号进行传输。载波的高频特性使得信号能以更高效的方式传播到远距离，同时方便利用频谱资源和区分不同信道。</p><p>简单来说，信号是内容，载波是运输工具，<strong>调制</strong>是将信号映射在载波的一种方式，用以实现无损的信息传递。</p><p>这里使用数字调制来解释，假设有比特流00，01，10，11，我们就可以用一个幅度表示两个比特，四个幅度表示这八个比特。我们用简化过的公式来表示这个信号：</p><span><span><span>s(t)=A⋅cos⁡(2πfct)s(t) = A \cdot \cos(2\pi f_c t)</span><span><span><span></span><span>s</span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>A</span><span></span><span>⋅</span><span></span></span><span><span></span><span>cos</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span></span><p>其中 <span><span>AA</span><span><span><span></span><span>A</span></span></span></span> 就是我们要发送的信号映射的幅度，<span><span>cos⁡(2πfct)\cos(2\pi f_c t)</span><span><span><span></span><span>cos</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span> 是我们的载波。如果我们将00，01，10，11映射在1，2，3，4这四个幅度上，依次发送，那么波形应该如以下图像所示：</p><p></p><figure><img alt="image.png" loading="lazy" width="4239" height="2856" src="/_astro/1739760459913_image.DEJpO6tc_Z1Ty8IC.webp" /><figcaption>image.png</figcaption></figure><p></p><p>这就是一个简化过的典型的4-ASK（四阶幅度键控，4-Amplitude Shift Keying），通过在载波的幅度上附加信息以实现通过载波传送信息。传统幅度调制通过改变载波的幅度传递信息，但其本质是<strong>单一维度的调制</strong>——所有信息都编码在幅度这一个自由度上。</p></section>
<section><h2>2. 正交性<a href="#2-正交性"><span>#</span></a></h2><p>这时候我们可以引出一个概念：<strong>正交性</strong>。</p><p>两个载波 <span><span>ϕ1(t)\phi_1(t)</span><span><span><span></span><span><span>ϕ</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 和 <span><span>ϕ2(t)\phi_2(t)</span><span><span><span></span><span><span>ϕ</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 在符号周期 <span><span>TT</span><span><span><span></span><span>T</span></span></span></span> 内满足正交条件：</p><span><span><span>∫0Tϕ1(t)⋅ϕ2(t)dt=0\int_{0}^{T}\phi_1(t) \cdot \phi_2(t) dt = 0</span><span><span><span></span><span><span>∫</span><span><span><span><span><span><span></span><span><span><span>0</span></span></span></span><span><span></span><span><span><span>T</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span><span>ϕ</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>⋅</span><span></span></span><span><span></span><span><span>ϕ</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>d</span><span>t</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span></span><p>如果我们让 <span><span>ϕ1(t)=sin⁡(2πfct)\phi_1(t) = \sin(2\pi f_c t)</span><span><span><span></span><span><span>ϕ</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>sin</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span>，<span><span>ϕ2(t)=cos⁡(2πfct)\phi_2(t) = \cos(2\pi f_c t)</span><span><span><span></span><span><span>ϕ</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>cos</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span>，通过简单的计算可以知道，这两个载波是正交的。</p><p>这意味着我们如果有一个信号 <span><span>s(t)=A⋅ϕ1(t)+B⋅ϕ2(t)s(t) = A \cdot \phi_1(t) + B \cdot \phi_2(t)</span><span><span><span></span><span>s</span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>A</span><span></span><span>⋅</span><span></span></span><span><span></span><span><span>ϕ</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>B</span><span></span><span>⋅</span><span></span></span><span><span></span><span><span>ϕ</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span>，也就是两个载波的叠加，从发送端发送，从接收端接收到后，可以通过正交性的原理重新剥离出两个信号：</p><span><span><span>A=∫0Ts(t)⋅sin⁡(2πfct)dtA = \int_{0}^{T}s(t) \cdot \sin(2\pi f_c t) dt</span><span><span><span></span><span>A</span><span></span><span>=</span><span></span></span><span><span></span><span><span>∫</span><span><span><span><span><span><span></span><span><span><span>0</span></span></span></span><span><span></span><span><span><span>T</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>s</span><span>(</span><span>t</span><span>)</span><span></span><span>⋅</span><span></span></span><span><span></span><span>sin</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span><span>d</span><span>t</span></span></span></span></span><span><span><span>B=∫0Ts(t)⋅cos⁡(2πfct)dtB = \int_{0}^{T}s(t) \cdot \cos(2\pi f_c t) dt</span><span><span><span></span><span>B</span><span></span><span>=</span><span></span></span><span><span></span><span><span>∫</span><span><span><span><span><span><span></span><span><span><span>0</span></span></span></span><span><span></span><span><span><span>T</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>s</span><span>(</span><span>t</span><span>)</span><span></span><span>⋅</span><span></span></span><span><span></span><span>cos</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span><span>d</span><span>t</span></span></span></span></span><p>这样我们就可以实现在一个频段下同时传输两个独立的载波，两个载波互不干扰且能完美的分离出来。</p></section>
<section><h2>3. I/Q调制<a href="#3-iq调制"><span>#</span></a></h2><p>在通信系统中，正交性为高效频谱利用提供了理论可能，但要将这种数学特性转化为实际技术，需要一种能将两路独立信号嵌入同一频段的调制方法——<strong>IQ调制</strong>（In-phase/Quadrature Modulation）。</p><p>传统调制技术（如AM或FM）仅利用单一维度传输信息，例如通过幅度或频率变化编码数据，这导致频谱效率低下、抗干扰能力弱，且难以扩展。例如，若想通过调幅传输4比特数据，需要定义16种不同的幅度等级，但噪声稍大便会导致幅度失真，误码率急剧上升；而若叠加多载波提升容量，硬件成本和功耗又会失控。正交性的出现打破了这一僵局：通过使用相位差90度的两个载波（如 <span><span>cos⁡(2πfct)\cos(2\pi f_c t)</span><span><span><span></span><span>cos</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span> 和 <span><span>sin⁡(2πfct)\sin(2\pi f_c t)</span><span><span><span></span><span>sin</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span>），可以在同一频段内并行传输两路独立信号，互不干扰。</p><p>IQ调制将这一理论付诸实践——它将数据拆分为<strong>同相分量（I路）<strong>和</strong>正交分量（Q路）</strong>，分别调制到两个正交载波上，再合成为单一信号：</p><span><span><span>s(t)=I(t)cos⁡(2πfct)−Q(t)sin⁡(2πfct)s(t) = I(t)\cos(2\pi f_c t) - Q(t)\sin(2\pi f_c t)</span><span><span><span></span><span>s</span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>I</span><span>(</span><span>t</span><span>)</span><span></span><span>cos</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span><span></span><span>−</span><span></span></span><span><span></span><span>Q</span><span>(</span><span>t</span><span>)</span><span></span><span>sin</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span></span><p>接收端通过正交解调，可精确分离出I和Q信号。这种设计不仅将频谱效率直接翻倍（从单边带的50%利用率提升至双边带100%），而传统单维度调制需复杂的反馈电路。更重要的是，IQ调制为高阶调制技术铺平了道路——通过在I/Q平面上灵活布置星座点，其中，I/Q平面是一个复平面。</p></section>
<section><h2>4. QAM （Quadrature Amplitude Modulation）正交幅度调制<a href="#4-qam-quadrature-amplitude-modulation正交幅度调制"><span>#</span></a></h2><p>I/Q调制中其中一个很重要的方法就是<strong>QAM</strong>（Quadrature Amplitude Modulation）正交幅度调制。<strong>QAM本质上是IQ调制的具体应用</strong>。</p><p>在QAM中，数据被分配到I和Q通道，分别对这两个分量的<strong>幅度进行调制</strong>（而非相位或频率），从而实现幅相联合调制。I和Q的幅度组合对应星座图中的不同符号。</p><p>我们可以直接把信息映射到二维的复平面上（I-Q坐标系），每个QAM符号由两个独立的幅度 <span><span>II</span><span><span><span></span><span>I</span></span></span></span> 和 <span><span>QQ</span><span><span><span></span><span>Q</span></span></span></span> 定义：</p><span><span><span>s(t)=I⋅cos⁡(2πfct)−Q⋅sin⁡(2πfct)s(t) = I \cdot \cos(2\pi f_c t) - Q \cdot \sin(2\pi f_c t)</span><span><span><span></span><span>s</span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>I</span><span></span><span>⋅</span><span></span></span><span><span></span><span>cos</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span><span></span><span>−</span><span></span></span><span><span></span><span>Q</span><span></span><span>⋅</span><span></span></span><span><span></span><span>sin</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span></span><p>或者用复数形式表示：</p><span><span><span>s(t)=Re{(I(t)+jQ(t))⋅ej2πfct}s(t) = \text{Re}\{(I(t) + jQ(t)) \cdot e^{j2\pi f_c t}\}</span><span><span><span></span><span>s</span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span>Re</span></span><span>{(</span><span>I</span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>j</span><span>Q</span><span>(</span><span>t</span><span>))</span><span></span><span>⋅</span><span></span></span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>j</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span></span></span></span></span></span></span></span></span><span>}</span></span></span></span></span><p>以4QAM举个例子，通过在星座图（二维复平面）中的四个点传递信息，其中每个点是一个符号，映射2比特的信息。</p><p></p><figure><img alt="image.png" loading="lazy" width="4953" height="2856" src="/_astro/1739768859117_image.DGTSjrAB_1Lb2DG.webp" /><figcaption>image.png</figcaption></figure><p></p><p>我们可以把00，01，11，10映射到四个点 <span><span>z1z_1</span><span><span><span></span><span><span>z</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>，<span><span>z3z_3</span><span><span><span></span><span><span>z</span><span><span><span><span><span><span></span><span><span>3</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>，<span><span>z4z_4</span><span><span><span></span><span><span>z</span><span><span><span><span><span><span></span><span><span>4</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>，<span><span>z2z_2</span><span><span><span></span><span><span>z</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 上，我们可以用复数表示为：<span><span>1+i1+i</span><span><span><span></span><span>1</span><span></span><span>+</span><span></span></span><span><span></span><span>i</span></span></span></span>，<span><span>−1+i-1+i</span><span><span><span></span><span>−</span><span>1</span><span></span><span>+</span><span></span></span><span><span></span><span>i</span></span></span></span>，<span><span>−1−i-1-i</span><span><span><span></span><span>−</span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span>i</span></span></span></span>，<span><span>1−i1-i</span><span><span><span></span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span>i</span></span></span></span>。如果从我们的信号的公式来看，就可以得知：</p><span><span><span>sRz1(t)=cos⁡(2πfct)−sin⁡(2πfct)s_{Rz1}(t) = \cos(2\pi f_c t) - \sin(2\pi f_c t)</span><span><span><span></span><span><span>s</span><span><span><span><span><span><span></span><span><span><span>R</span><span>z</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>cos</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span><span></span><span>−</span><span></span></span><span><span></span><span>sin</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span></span><span><span><span>sRz2(t)=cos⁡(2πfct)+sin⁡(2πfct)s_{Rz2}(t) = \cos(2\pi f_c t) + \sin(2\pi f_c t)</span><span><span><span></span><span><span>s</span><span><span><span><span><span><span></span><span><span><span>R</span><span>z</span><span>2</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>cos</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>sin</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span></span><span><span><span>sRz3(t)=−cos⁡(2πfct)−sin⁡(2πfct)s_{Rz3}(t) = -\cos(2\pi f_c t) - \sin(2\pi f_c t)</span><span><span><span></span><span><span>s</span><span><span><span><span><span><span></span><span><span><span>R</span><span>z</span><span>3</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>−</span><span></span><span>cos</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span><span></span><span>−</span><span></span></span><span><span></span><span>sin</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span></span><span><span><span>sRz4(t)=−cos⁡(2πfct)+sin⁡(2πfct)s_{Rz4}(t) = -\cos(2\pi f_c t) + \sin(2\pi f_c t)</span><span><span><span></span><span><span>s</span><span><span><span><span><span><span></span><span><span><span>R</span><span>z</span><span>4</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>−</span><span></span><span>cos</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>sin</span><span>(</span><span>2</span><span>π</span><span><span>f</span><span><span><span><span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>t</span><span>)</span></span></span></span></span><p>这就是四个符号的QAM信号，依次发送即可。</p></section>
<section><h2>5. OFDM （Orthogonal Frequency Division Multiplexing）正交频分复用技术<a href="#5-ofdm-orthogonal-frequency-division-multiplexing正交频分复用技术"><span>#</span></a></h2><p>尽管QAM在理想信道中能实现高频谱效率，但在<strong>宽带多径信道</strong>中面临以下问题：</p><p><strong>符号间干扰（ISI, Inter-Symbol Interference）</strong>：高速传输时，符号周期（<span><span>TT</span><span><span><span></span><span>T</span></span></span></span>）缩短，多径时延扩展可能超过 <span><span>TT</span><span><span><span></span><span>T</span></span></span></span>，导致相邻符号在时域重叠，接收端难以区分。尤其是当时延超过符号周期的时候，这种难以区分的情况就很严重。</p><p><strong>复杂均衡需求</strong>：单载波QAM需要高阶时域均衡器（如判决反馈均衡器DFE）来消除ISI，但计算复杂度随带宽指数增长。</p><p><strong>频率选择性衰落</strong>：宽带信道不同频段的衰落差异显著，导致部分子载波深度衰落，整体性能受限。</p><p>而OFDM基本上做的最重要的两件事情就是将多个符号时间为 <span><span>1/Ts1/T_s</span><span><span><span></span><span>1/</span><span><span>T</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 的QAM符号直接转换为 <span><span>N/TsN/T_s</span><span><span><span></span><span>N</span><span>/</span><span><span>T</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 时域的OFDM符号，也就是说延长了符号周期时间，并且直接生成时域信号。</p><p>而生成时域信号最重要的方法就是IFFT。</p><p>在OFDM系统中，<strong>逆快速傅里叶变换（IFFT）</strong> 用于将频域符号转换为时域信号。其数学公式基于离散傅里叶逆变换（IDFT），定义如下：</p><span><span><span>x[n]=1N∑k=0N−1X[k]⋅ej2πkn/Nx[n] = \frac{1}{N} \sum_{k = 0}^{N - 1} X[k] \cdot e^{j2\pi kn/N}</span><span><span><span></span><span>x</span><span>[</span><span>n</span><span>]</span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>N</span></span></span><span><span></span><span></span></span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span><span><span><span><span><span></span><span><span><span>k</span><span>=</span><span>0</span></span></span></span><span><span></span><span><span>∑</span></span></span><span><span></span><span><span><span>N</span><span>−</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>X</span><span>[</span><span>k</span><span>]</span><span></span><span>⋅</span><span></span></span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>j</span><span>2</span><span>π</span><span>k</span><span>n</span><span>/</span><span>N</span></span></span></span></span></span></span></span></span></span></span></span></span><p>其中：</p><ul>
<li><span><span>X[k]X[k]</span><span><span><span></span><span>X</span><span>[</span><span>k</span><span>]</span></span></span></span>：频域中第 <span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 个子载波的复数符号（例如QAM符号）。</li>
<li><span><span>x[n]x[n]</span><span><span><span></span><span>x</span><span>[</span><span>n</span><span>]</span></span></span></span>：时域信号的第 <span><span>nn</span><span><span><span></span><span>n</span></span></span></span> 个采样点。</li>
<li><span><span>NN</span><span><span><span></span><span>N</span></span></span></span>：子载波总数。</li>
</ul><p>IFFT有着极佳的计算性能，硬件实现的复杂度也较低。</p><p>而IFFT输出的就是复数序列，假设一个QAM信号的符号时间是 <span><span>1/Ts1/T_s</span><span><span><span></span><span>1/</span><span><span>T</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>，有 <span><span>NN</span><span><span><span></span><span>N</span></span></span></span> 个OFDM子载波，那么一个OFDM的符号有 <span><span>NN</span><span><span><span></span><span>N</span></span></span></span> 个复数，且总符号时间为 <span><span>N/TsN/T_s</span><span><span><span></span><span>N</span><span>/</span><span><span>T</span><span><span><span><span><span><span></span><span><span>s</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>。这就避免了符号周期过短导致的接收端难以区分。</p><p>另一个OFDM重要的步骤就是<strong>CP</strong>（<strong>Cyclic Prefix</strong>）。</p><p>在无线通信中，信号会通过不同的路径（例如直接路径和反射路径）到达接收端，这种现象称为多径效应。由于路径长度的差异，不同路径的信号到达时间会有延迟，导致<strong>符号间干扰（ISI，Inter-Symbol Interference）</strong>。在OFDM中，如果前一个符号的信号延迟扩展到下一个符号的接收时间内，就会破坏子载波的正交性，进而影响接收端正确解调数据。</p><p>为了解决多径效应带来的ISI问题，OFDM引入了循环前缀，在发送端，将每个OFDM符号的末尾部分数据复制到符号的前面，形成一个前缀。这个前缀就是“循环前缀”，因为它是从符号尾部循环取出的。CP的长度通常要大于信道的最大时延扩展（即多径效应的最长延迟），这样可以确保多径分量不会干扰到下一个符号的有效数据部分。CP被加到每个OFDM符号的开头，构成一个完整的传输符号：CP + 数据部分。</p><p>在接收端，由于多径效应，接收到的信号是多个延迟版本的叠加。有了CP，即使存在时延扩展，接收端只需丢弃CP部分（因为它吸收了多径干扰），然后从有效数据部分开始采样。这样，前一个符号的多径分量就不会影响到当前符号的有效数据，避免了ISI。</p><p>通过信道后，FFT后再解调QAM，就能得到我们的数据流了。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/macdisableswap/</id>
      <title type="text">macOS 关闭Swap</title>
      <published>2025-02-12T00:00:00.000Z</published>
      <updated>2025-02-12T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/macdisableswap/"/>
      <summary type="text">通过调整内存策略在macOS上禁用Swap交换空间</summary>
      <content type="html"><![CDATA[<section><h2>1. 关闭SIP<a href="#1-关闭sip"><span>#</span></a></h2><p>关机后开机并继续按住电源按钮直到开启启动选项窗口，进入恢复模式。（Apple Silicon）</p><p>在终端中输入：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>csrutil</span><span> </span><span>disable</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>2. 调整内存策略<a href="#2-调整内存策略"><span>#</span></a></h2><p>重新启动Mac后</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>nvram</span><span> </span><span>boot-args="vm_compressor=2"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>就可以设置为<code>仅压缩、不使用swap</code></p><p>至此就关闭了sawp。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/openlitespeed/</id>
      <title type="text">部署OpenLiteSpeed并安装WordPress</title>
      <published>2025-01-17T00:00:00.000Z</published>
      <updated>2025-01-17T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/openlitespeed/"/>
      <summary type="text">使用高性能Web服务器OpenLiteSpeed搭建WordPress博客</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>OpenLiteSpeed 相对于 Nginx 和 Caddy 有着无与伦比的性能优势，对于羸弱的低配VPS，使用OpenLiteSpeed能够显著的提升性能。</p><p>OpenLiteSpeed 是 LiteSpeed Technologies 开发的一款开源、高性能的 Web 服务器，特别适合托管动态和静态网站。它以低资源消耗和出色的性能而闻名，支持现代的 Web 技术和协议，如 HTTP/3、QUIC 和 TLS。</p><p><img alt="" loading="lazy" width="725" height="375" src="/_astro/ols-wp-cache.Cdy7qIGM_Z1JKybu.webp" /></p><p><strong>主要特点：</strong></p><ol>
<li>
<p><strong>高性能</strong>：</p>
<ul>
<li>
<p>使用基于事件驱动的架构，高效处理并发连接。</p>
</li>
<li>
<p>内置的 LiteSpeed 缓存（LSCache）提高动态内容的加载速度。</p>
</li>
</ul>
</li>
<li>
<p><strong>开源</strong>：</p>
<ul>
<li>免费使用，代码可供检查和修改。</li>
</ul>
</li>
<li>
<p><strong>支持多种语言和框架</strong>：</p>
<ul>
<li>包括 PHP、Python、Ruby 等。与 PHP 结合时，使用 LiteSpeed 的专用 SAPI（LSAPI），比传统的 FastCGI 更快。</li>
</ul>
</li>
<li>
<p><strong>易于管理</strong>：</p>
<ul>
<li>提供 Web GUI 管理界面，简化服务器配置。</li>
</ul>
</li>
<li>
<p><strong>安全性</strong>：</p>
<ul>
<li>内置防火墙规则和抗 DDoS 攻击功能。</li>
</ul>
</li>
</ol></section>
<section><h2>安装OpenLiteSpeed<a href="#安装openlitespeed"><span>#</span></a></h2><p>首先，通过官方的一键安装脚本安装 OpenLiteSpeed 和 Wordpress</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bash</span><span> </span><span>&lt;( </span><span>curl</span><span> </span><span>-k</span><span> https://raw.githubusercontent.com/litespeedtech/ols1clk/master/ols1clk.sh )</span><span> </span><span>-w</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装完成后直接打开安装所在主机的 <code>https://ip:7080</code> 进入管理面板。其中用户名和密码会显示在终端的日志中(<code>WebAdmin username</code>, <code>WebAdmin password</code>)。</p><p>直接用IP地址访问你的Wordpress，完成初始的设置后会自动进入后台面板，在<code>设置</code>-<code>常规</code>中，将Wordpress地址和站点地址改为<code>https://yourdomain.com</code> 。</p></section>
<section><h2>配置证书<a href="#配置证书"><span>#</span></a></h2><p>接下来为Wordpress申请SSL证书，这里使用certbot申请Let’s Encrypt证书：</p><p>因为本文使用CloudFlare代理，在更新证书的时候无法验证域名的解析，所以此处将通过CloudFlare官方的令牌以验证解析。</p><p>在主机安装相应的插件(Debian为例)：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>python3-certbot-dns-cloudflare</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在CloudFlare的<code>管理账户</code>-<code>账户API令牌</code>选项卡中，创建一个令牌，选择<code>编辑区域DNS模板</code>。</p><p><code>区域资源</code>中选择<code>特定区域</code>，并且选择你的域名，点击创建。</p><p>复制得到的API令牌，并在你的主机中创建一个文件 <code>/etc/letsencrypt/cloudflare.ini</code></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vim</span><span> </span><span>/etc/letsencrypt/cloudflare.ini</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>填充以下内容，并将<code>YOUR_CLOUDFLARE_API_TOKEN</code>替换为你刚刚复制的API令牌：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>dns_cloudflare_api_token</span><span><span> </span><span>=</span><span> YOUR_CLOUDFLARE_API_TOKEN</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行如下命令申请证书，将<code>yourdomain.com</code>替换为你的域名。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>certbot</span><span> </span><span>certonly</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>    </span><span>--dns-cloudflare</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>    </span><span>--dns-cloudflare-credentials</span><span> </span><span>/etc/letsencrypt/cloudflare.ini</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>    </span><span>-d</span><span> </span><span>yourdomain.com</span><span> </span><span>-d</span><span> </span><span>www.yourdomain.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行完毕后会显示证书和私钥的目录。</p><p><strong>确保你已经将你的域名成功解析到你的主机。</strong></p><p>接下来在 OpenLiteSpeed 的管理面板中，选择监听器-wordpressssl-SSL，将私钥文件和证书文件编辑为生成的证书的目录，保存后并右上角重启OpenLiteSpeed。</p><p>至此已经可以通过HTTPS访问你的域名，管理Wordpress了。</p></section>
<section><h2>自动更新证书<a href="#自动更新证书"><span>#</span></a></h2><p>Let’s Encrypt需要每三个月更新一次，因此使用crontab定期自动更新证书。</p><p>编辑crontab：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>crontab</span><span> </span><span>-e</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>添加如下内容：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>0</span><span> </span><span>3</span><span> </span><span>*</span><span> </span><span>*</span><span> </span><span>*</span><span> </span><span>certbot</span><span> </span><span>renew</span><span> </span><span>--quiet</span><span> </span><span>--deploy-hook</span><span> </span><span>"systemctl reload lsws"</span><span> &gt;&gt; </span><span>/var/log/certbot-renew.log</span><span> 2&gt;&amp;1</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>至此就可以自动更新证书了。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/ssh/</id>
      <title type="text">通过密钥对访问SSH服务端</title>
      <published>2024-12-20T00:00:00.000Z</published>
      <updated>2024-12-20T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/ssh/"/>
      <summary type="text">在Windows和macOS上创建SSH密钥对并配置免密登录</summary>
      <content type="html"><![CDATA[<p>通常情况下，人们喜欢使用密码的方式访问ssh服务端，多半是因为设置密钥对比较复杂，以及在其他陌生的客户端的情况下，使用密码有更好的便捷性。</p>
<p>但是当处于固定客户端的情况下，仅仅设置一次密钥对就可以达到一劳永逸的效果。本文将简单记录在常见的操作系统下创建密钥对并连接Linux服务器。</p>
<section><h2>SSH和密钥对<a href="#ssh和密钥对"><span>#</span></a></h2><p><strong>SSH (Secure Shell)</strong> 是一种用于安全远程登录和管理网络设备的协议。它通过加密技术确保通信的安全性，常用于在不安全的网络中安全地访问远程服务器。</p><p><strong>私钥 (Private Key)</strong>:</p><ul>
<li>
<p>存放在本地计算机，必须妥善保管，不能泄露。</p>
</li>
<li>
<p>用于解密通过公钥加密的数据，也可用于生成数字签名。</p>
</li>
</ul><p><strong>公钥 (Public Key)</strong>:</p><ul>
<li>
<p>可以安全地共享给其他人或服务器。</p>
</li>
<li>
<p>存放在远程服务器中，用于验证连接是否由对应的私钥拥有者发起。</p>
</li>
</ul><p><strong>密钥认证过程</strong>：</p><ol>
<li>
<p>生成密钥对：在本地生成公钥和私钥。</p>
</li>
<li>
<p>部署公钥：将公钥上传到远程服务器。</p>
</li>
<li>
<p>登录时验证：SSH 客户端用私钥对数据签名，服务器通过公钥验证签名是否有效。如果匹配，则允许登录。</p>
</li>
</ol><p>在生成公钥和私钥时，常用的算法包括 <strong>RSA</strong>、<strong>ECDSA</strong>、<strong>ED25519</strong> 和 <strong>DSA</strong>，该选择哪种算法呢？</p>

<table><thead><tr><th><strong>算法</strong></th><th><strong>密钥长度</strong></th><th><strong>性能</strong></th><th><strong>安全性</strong></th><th><strong>兼容性</strong></th><th><strong>推荐场景</strong></th></tr></thead><tbody><tr><td><strong>RSA</strong></td><td>2048~4096</td><td>较快</td><td>高</td><td>非常好</td><td>需要广泛兼容性的场景</td></tr><tr><td><strong>ECDSA</strong></td><td>256~512</td><td>快</td><td>高</td><td>较好</td><td>需要高效和地空间占用的场景</td></tr><tr><td><strong>ED25519</strong></td><td>256</td><td>非常快</td><td>很高</td><td>较好</td><td>新型主流系统</td></tr><tr><td><strong>DSA</strong></td><td>1024</td><td>慢</td><td>较低</td><td>较差</td><td>干啥啥不行，扔了吧</td></tr></tbody></table><p>显而易见，最好选择ED25519算法。</p></section>
<section><h2>不同平台创建密钥对通过SSH访问 Linux（Debian 为例）<a href="#不同平台创建密钥对通过ssh访问-linuxdebian-为例"><span>#</span></a></h2><p>这里主要介绍通过Windows以及MacOS访问Debian服务器的方法。</p><section><h3>Windows 10/11<a href="#windows-1011"><span>#</span></a></h3><p>在Powershell中执行以下命令生成密钥对，<code>your_key_name</code>是创建的密钥的名字，用于辨别。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span>ssh</span><span>-</span><span>keygen </span><span>-</span><span>t ed25519 </span></span><span>-f</span><span> </span><span>$env:USERPROFILE</span><span>\.ssh\your_key_name</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>创建后，会提示输入passphrase，一般情况下直接回车跳过就好。在Windows的用户文件夹中的.ssh目录中，可以找到刚刚创建的密钥对，其中key是你自己的私钥，pub是公钥，需要上传到你要连接的服务器。</p><p>然而Powershell并没有<code>ssh-copy-id</code>这种东西，所以我们使用这种方案：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cat </span><span><span>"</span><span>$</span></span><span>env:USERPROFILE</span><span>\.ssh\your_key_name.pub"</span><span><span> | ssh </span><span>-</span><span>i </span></span><span><span>"</span><span>$</span></span><span>env:USERPROFILE</span><span>\.ssh\your_key_name"</span><span> user</span><span>@server</span><span> </span><span>"umask 077; test -d .ssh || mkdir .ssh ; cat &gt;&gt; .ssh/authorized_keys || exit 1"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>其中，<code>user@server</code>是你登陆服务器的用户名和地址，把里面对应的密钥名改成自己的。运行之后会要求输入密码，直接输入密码就好，之后使用如下命令就可以直接登录了。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span>ssh </span><span>-</span><span>i </span></span><span><span>"</span><span>$</span></span><span>env:USERPROFILE</span><span>\.ssh\your_key_name"</span><span> user</span><span>@server</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果你还是嫌麻烦每次都要输入私钥的地址，可以添加到Powershell的fuction中：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>your_alias_name</span><span> {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>ssh </span><span>-</span><span>i </span><span><span>"</span><span>$</span></span><span>env:USERPROFILE</span><span>\.ssh\your_key_name"</span><span> user</span><span>@server</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>之后直接通过 <code>your_alias_name</code> 在Powershell中执行就可以登录了。</p></section><section><h3>MacOS Sequoia<a href="#macos-sequoia"><span>#</span></a></h3><p>理论上Catalina之后的版本都可以</p><p>在MacOS终端zsh中运行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ssh-keygen</span><span> </span><span>-t</span><span> </span><span>ed25519</span><span> </span><span>-f</span><span> </span><span>~/.ssh/your_key_name</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后通过ssh-copy-id将公钥上传到服务器：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ssh-copy-id</span><span> </span><span>-i</span><span> </span><span>~/.ssh/your_key_name.pub</span><span> </span><span>user@server</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>输入密码之后就完成了。你可以通过在终端中运行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ssh</span><span> </span><span>-i</span><span> </span><span>"~/.ssh/your_key_name"</span><span> </span><span>user@server</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>直接登录。</p><p>为了简便操作，可以设置alias快速登录（在MacOS Catalina之后，终端默认使用zsh，这里以zsh为例）。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vim</span><span> </span><span>~/.zshrc</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>添加你的别名</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>alias</span><span> </span><span>server_name</span><span>=</span><span>'ssh -i ~/.ssh/your_key_name user@server'</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后保存并生效</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>source</span><span> </span><span>~/.zshrc</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后你就可以直接用alias别名来快速登录了！</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/adbuninstall/</id>
      <title type="text">日版 Xperia 预装垃圾卸载</title>
      <published>2023-09-23T00:00:00.000Z</published>
      <updated>2023-09-23T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/adbuninstall/"/>
      <summary type="text">适用于Xperia日版的预装应用卸载命令集合</summary>
      <content type="html"><![CDATA[<p>适用于Xperia5 ii 日版通用版</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.tencent.qqspmi</span></div></div><div><div><div>2</div></div><div><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.linkedin.android</span></div></div><div><div><div>3</div></div><div><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.activision.callofduty.shooter</span></div></div><div><div><div>4</div></div><div><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.facebook.katana</span></div></div><div><div><div>5</div></div><div><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.netflix.mediaclient</span></div></div><div><div><div>6</div></div><div><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>jp.sony.spot.sp</span></div></div><div><div><div>7</div></div><div><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.sony.drbd.reader.other.jp</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>适用于Xperia</span><span> </span><span>XZ3</span><span> </span><span>Docomo版本</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.amazon.mShop.android.shopping</span></div></div><div><div><div>2</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.amazon.kindle</span></div></div><div><div><div>3</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.instagram.android</span></div></div><div><div><div>4</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.facebook.katana</span></div></div><div><div><div>5</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.facebook.orca</span></div></div><div><div><div>6</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.facebook.appmanager</span></div></div><div><div><div>7</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.facebook.system</span></div></div><div><div><div>8</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>jp.co.lawson.android</span></div></div><div><div><div>9</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>jp.co.fsi.fs1seg</span></div></div><div><div><div>10</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>jp.co.capcom.android.explore</span></div></div><div><div><div>11</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.forwardworks.mingol</span></div></div><div><div><div>12</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.sega.d2megaten</span></div></div><div><div><div>13</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>jp.co.nttdocomo.dbook</span></div></div><div><div><div>14</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>jp.co.mcdonalds.android</span></div></div><div><div><div>15</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>jp.id_credit_sp.android</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span># docomo 系列预装（建议删除）</span></div></div><div><div><div>18</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>jp.co.nttdocomo.lcsapp</span></div></div><div><div><div>19</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.photocollection</span></div></div><div><div><div>20</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.anmane2</span></div></div><div><div><div>21</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.databackup</span></div></div><div><div><div>22</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.screenlockservice</span></div></div><div><div><div>23</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.felicaremotelock</span></div></div><div><div><div>24</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.dmenu2</span></div></div><div><div><div>25</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.dpoint</span></div></div><div><div><div>26</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.schedulememo</span></div></div><div><div><div>27</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.pf.dcmwappush</span></div></div><div><div><div>28</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.mydocomo</span></div></div><div><div><div>29</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.mascot</span></div></div><div><div><div>30</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.docomoset</span></div></div><div><div><div>31</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.keitai.payment</span></div></div><div><div><div>32</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.voicetranslation</span></div></div><div><div><div>33</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.kittingmanager</span></div></div><div><div><div>34</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.applicationmanager</span></div></div><div><div><div>35</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.cloudset</span></div></div><div><div><div>36</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.anshinsecurity</span></div></div><div><div><div>37</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.apnsw</span></div></div><div><div><div>38</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.dhome</span></div></div><div><div><div>39</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.store</span></div></div><div><div><div>40</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.sdcardbackup</span></div></div><div><div><div>41</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.accountwipe</span></div></div><div><div><div>42</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.cloudstorageservice</span></div></div><div><div><div>43</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.devicehelp</span></div></div><div><div><div>44</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.initialization</span></div></div><div><div><div>45</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.idmanager</span></div></div><div><div><div>46</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.voiceeditor</span></div></div><div><div><div>47</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.accountauthenticator</span></div></div><div><div><div>48</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.msg</span></div></div><div><div><div>49</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.bugreport</span></div></div><div><div><div>50</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.moneyrecord</span></div></div><div><div><div>51</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.osv</span></div></div><div><div><div>52</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.atf</span></div></div><div><div><div>53</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.remotelock</span></div></div><div><div><div>54</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.areamail</span></div></div><div><div><div>55</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.carriermail</span></div></div><div><div><div>56</div></div><div><span>./adb</span><span> </span><span>shell</span><span> </span><span>pm</span><span> </span><span>uninstall</span><span> </span><span>--user</span><span> </span><span>0</span><span> </span><span>com.nttdocomo.android.dhealthcare</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/arrayandstring/</id>
      <title type="text">数据结构 数组和字符串</title>
      <published>2023-09-05T00:00:00.000Z</published>
      <updated>2023-09-05T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/arrayandstring/"/>
      <summary type="text">深入理解数组、列表和字符串的数据结构特性与操作</summary>
      <content type="html"><![CDATA[<section><h2>1. 数组、列表和集合的区别<a href="#1-数组列表和集合的区别"><span>#</span></a></h2><section><h3>集合<a href="#集合"><span>#</span></a></h3><p><strong>由一个或多个确定的元素所构成的整体</strong></p><p>集合的特性：</p><ul>
<li>
<p>集合内的元素不一定相同</p>
</li>
<li>
<p>集合是无序的</p>
</li>
</ul></section><section><h3>列表<a href="#列表"><span>#</span></a></h3><p><strong>列表是一种有顺序的长度可变的集合</strong></p><p>列表的特性：</p><ul>
<li>
<p>列表是有序的</p>
</li>
<li>
<p>列表的长度是可变的</p>
</li>
<li>
<p>列表的元素地址是可以不连续的（链表）</p>
</li>
</ul></section><section><h3>数组<a href="#数组"><span>#</span></a></h3><p><strong>数组是列表的一种实现方式</strong></p><p>数组的特性：</p><ul>
<li>
<p>数组具有索引，用来标记数据数组中的位置</p>
</li>
<li>
<p>数组在内存中数据是连续的，且每个元素占相同大小的内存</p>
</li>
</ul></section></section>
<section><h2>2. 数组的操作<a href="#2-数组的操作"><span>#</span></a></h2><p>数据在内存中分散分布，而数组在内存中是连续的。在创建数组时，计算机会为数组申请一段<strong>连续的</strong>空间，并且记录下<strong>第一个</strong>元素空间的内存地址（<strong>假设为114514，且数组元素大小为1）<strong>作为数组的位置，那么当需要查询数组中第5个元素时计算机会进行以下操作：寻找到数组的位置</strong>（114514）</strong>，在<strong>114514</strong>的基础上**+5**，就得到了第5个元素的位置，读取**（114514+5）**这个地址内的值。</p><p>Tips：在32位的CPU中（不考虑地址加法器），CPU的寻址范围是**（0~2^32-1）**，内存的每一个格子是一个字节（Byte），因此CPU最多可以查询2^32个格子的内存，2^32 * 1Byte ≈ 4 GigaByte，因此最大支持4GB的内存。需要注意的是，上面的例子中为了方便把数组元素大小设为1，而在实际上，例如在C++中，int型的数组元素大小为32bit（4Byte），因此每一个元素占4个Byte，在内存中实际上占四个格子，也就是说每次遍历元素的时候，地址需要+4。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> </span><span>main</span><span>() {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>int</span><span> </span><span>arr</span><span>[</span><span>5</span><span>];</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>std::</span><span>cout</span><span>&lt;&lt;</span><span>arr</span><span>&lt;&lt;</span><span>"</span><span>\n</span><span>"</span><span>;</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>std::</span><span>cout</span><span><span>&lt;&lt;</span><span>&amp;</span></span><span>arr</span><span>[</span><span>1</span><span>]</span><span>&lt;&lt;</span><span>"</span><span>\n</span><span>"</span><span>;</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>std::</span><span>cout</span><span><span>&lt;&lt;</span><span>&amp;</span></span><span>arr</span><span>[</span><span>2</span><span>]</span><span>&lt;&lt;</span><span>"</span><span>\n</span><span>"</span><span>;</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>std::</span><span>cout</span><span><span>&lt;&lt;</span><span>&amp;</span></span><span>arr</span><span>[</span><span>3</span><span>]</span><span>&lt;&lt;</span><span>"</span><span>\n</span><span>"</span><span>;</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>std::</span><span>cout</span><span><span>&lt;&lt;</span><span>&amp;</span></span><span>arr</span><span>[</span><span>4</span><span>]</span><span>&lt;&lt;</span><span>"</span><span>\n</span><span>"</span><span>;</span></div></div><div><div><div>8</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>9</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在以上的C++程序中，创建了一个大小为5的int类型的数组，C++中int数组默认为4字节。然后打印出数组中每个元素的地址：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>0x6d3cfffa40</span></div></div><div><div><div>2</div></div><div><span>0x6d3cfffa44</span></div></div><div><div><div>3</div></div><div><span>0x6d3cfffa48</span></div></div><div><div><div>4</div></div><div><span>0x6d3cfffa4c</span></div></div><div><div><div>5</div></div><div><span>0x6d3cfffa50</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>可以看到地址是连续的十六进制，且每个元素之间的地址相差4个位置，也就是4个字节。</p><section><h3>读取元素<a href="#读取元素"><span>#</span></a></h3><p>一旦知道了数组的第一个元素的地址，很快就可以通过加法得出所需要访问的元素的地址，因此获取地址的时时间复杂度是常数级O(1)。</p></section><section><h3>查找元素<a href="#查找元素"><span>#</span></a></h3><p>而在数组中寻找一个元素，则需要遍历，从一侧元素遍历到另一侧，最坏的情况是遍历n个元素，因此查询元素值的时间复杂度是O(n)。</p></section><section><h3>插入元素<a href="#插入元素"><span>#</span></a></h3><p>由于数组是连续的，当需要插入一个元素时（不包括插入到两侧），需要将插入的位置后面的原有的元素全部后移一位，因此数组的插入是十分浪费时间的。</p></section><section><h3>删除元素<a href="#删除元素"><span>#</span></a></h3><p>删除元素和插入元素相似，当在连续的数组中删除一个元素时（不包括删除两侧的元素），需要将被删除的后面的元素全部前移一位。</p></section></section>
<section><h2>3. 二维数组<a href="#3-二维数组"><span>#</span></a></h2><p>二维数组是一种特殊的数组，它将一维数组中的每一个元素都变成了一个数组。但是二维数组本质上还是一个一维数组，只是在逻辑上是二维的，形如矩阵。同样二维数组的第一行第一个的地址A[0][0]的地址被用来作为二维数组的地址。</p></section>
<section><h2>4. 字符串<a href="#4-字符串"><span>#</span></a></h2><section><h3>字符串的基本操作对象是字符串的整体或字串<a href="#字符串的基本操作对象是字符串的整体或字串"><span>#</span></a></h3><p>通常字符串会整体或者分块操作，而不是将字符串中的每一个元素单独操作，提高了字符操作的便利性。</p></section><section><h3>比较函数<a href="#比较函数"><span>#</span></a></h3><p>在不同语言中，字符串有不同的比较方法，在C++、Python中可以使用 ”==“进行比较，但是在Java中无法使用”==“，实际上只会去比较两个对象是否是一个对象。</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/oraclecmd/</id>
      <title type="text">Debian 自用初始化</title>
      <published>2023-09-04T00:00:00.000Z</published>
      <updated>2023-09-04T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/oraclecmd/"/>
      <summary type="text">Debian VPS 初始化配置和常用命令</summary>
      <content type="html"><![CDATA[<section><h2>初始化安装<a href="#初始化安装"><span>#</span></a></h2><section><h3>VPS 重装 Debian11<a href="#vps-重装-debian11"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bash</span><span> </span><span>&lt;(</span><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>-qO-</span><span> 'https://www.moeelf.com/attachment/LinuxShell/InstallNET.sh')</span><span> </span><span>-d</span><span> </span><span>11</span><span> </span><span>-v</span><span> </span><span>64</span><span> </span><span>-a</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Oracle vps SSH登录初始化脚本<a href="#oracle-vps-ssh登录初始化脚本"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/bash</span></div></div><div><div><div>2</div></div><div><span>echo</span><span> </span><span>root:password123789</span><span> |</span><span>sudo</span><span> </span><span>chpasswd</span><span> </span><span>root</span></div></div><div><div><div>3</div></div><div><span>sudo</span><span> </span><span>sed</span><span> </span><span>-i</span><span> </span><span>'s/^#\?PermitRootLogin.*/PermitRootLogin yes/g'</span><span> </span><span>/etc/ssh/sshd_config</span><span>;</span></div></div><div><div><div>4</div></div><div><span>sudo</span><span> </span><span>sed</span><span> </span><span>-i</span><span> </span><span>'s/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g'</span><span> </span><span>/etc/ssh/sshd_config</span><span>;</span></div></div><div><div><div>5</div></div><div><span>sudo</span><span> </span><span>service</span><span> </span><span>sshd</span><span> </span><span>restart</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Debian11 换源<a href="#debian11-换源"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cat</span><span> &gt; </span><span>/etc/apt/sources.list</span><span> &lt;&lt; </span><span>EOF</span></div></div><div><div><div>2</div></div><div><span>deb http://deb.debian.org/debian/ bullseye main non-free contrib</span></div></div><div><div><div>3</div></div><div><span>deb http://deb.debian.org/debian/ bullseye-updates main non-free contrib</span></div></div><div><div><div>4</div></div><div><span>deb-src http://deb.debian.org/debian/ bullseye main non-free contrib</span></div></div><div><div><div>5</div></div><div><span>deb-src http://deb.debian.org/debian/ bullseye-updates main non-free contrib</span></div></div><div><div><div>6</div></div><div><span>deb http://deb.debian.org/debian/ bullseye-backports main contrib non-free</span></div></div><div><div><div>7</div></div><div><span>deb-src http://deb.debian.org/debian/ bullseye-backports main contrib non-free</span></div></div><div><div><div>8</div></div><div><span>deb http://deb.debian.org/debian-security/ bullseye-security main contrib non-free</span></div></div><div><div><div>9</div></div><div><span>deb-src http://deb.debian.org/debian-security/ bullseye-security main contrib non-free</span></div></div><div><div><div>10</div></div><div><span>EOF</span></div></div><div><div><div>11</div></div><div><span>apt-get</span><span> </span><span>update</span></div></div><div><div><div>12</div></div><div><span>apt-get</span><span> </span><span>upgrade</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>操作自定义管理<a href="#操作自定义管理"><span>#</span></a></h2><section><h3>配置初始 sshd 服务<a href="#配置初始-sshd-服务"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vim</span><span> </span><span>/etc/ssh/sshd_config</span></div></div><div><div><div>2</div></div><div><span>systemctl</span><span> </span><span>restart</span><span> </span><span>sshd</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>常用包安装<a href="#常用包安装"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>update</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>sudo</span><span> </span><span>-y</span></div></div><div><div><div>3</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>vim</span><span> </span><span>-y</span></div></div><div><div><div>4</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>curl</span><span> </span><span>-y</span></div></div><div><div><div>5</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>wget</span><span> </span><span>-y</span></div></div><div><div><div>6</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>ufw</span><span> </span><span>-y</span></div></div><div><div><div>7</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>zip</span><span> </span><span>-y</span></div></div><div><div><div>8</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>screen</span><span> </span><span>-y</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>特殊用途常用安装<a href="#特殊用途常用安装"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>update</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>git</span><span> </span><span>-y</span></div></div><div><div><div>3</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>python3</span><span> </span><span>-y</span></div></div><div><div><div>4</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>pip</span><span> </span><span>-y</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>UFW 防火墙<a href="#ufw-防火墙"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ufw</span><span> </span><span>allow</span><span> </span><span>8080</span></div></div><div><div><div>2</div></div><div><span>ufw</span><span> </span><span>allow</span><span> </span><span>443</span></div></div><div><div><div>3</div></div><div><span>ufw</span><span> </span><span>allow</span><span> </span><span>22</span></div></div><div><div><div>4</div></div><div><span>ufw</span><span> </span><span>enable</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>Swap 设置<a href="#swap-设置"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>-q</span><span> </span><span>https://raw.githubusercontent.com/Dreamscape315/Swap_Manager/main/Swap_Manager.sh</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>+x</span><span> </span><span>Swap_Manager.sh</span><span> &amp;&amp; </span><span>sudo</span><span> </span><span>./Swap_Manager.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>Docker 相关<a href="#docker-相关"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>docker-ce</span><span> </span><span>docker-ce-cli</span><span> </span><span>containerd.io</span><span> </span><span>-y</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>system</span><span> </span><span>prune</span><span> </span><span>-a</span><span> </span><span>--volumes</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>]]></content>
    </entry>
    <entry>
      <id>https://fiction.spaplex.org/posts/reborn/</id>
      <title type="text">一次重新开始</title>
      <published>2023-06-11T00:00:00.000Z</published>
      <updated>2023-06-11T00:00:00.000Z</updated>
      <author><name>Akatsuki Sky</name></author>
      <link rel="alternate" href="https://fiction.spaplex.org/posts/reborn/"/>
      <summary type="text">灾难后，一切都毁灭于虚空，一切都要重新开始。</summary>
      <content type="html"><![CDATA[<p>灾难后，一切都毁灭于虚空，一切都要重新开始。</p>]]></content>
    </entry>
</feed>
