<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>AI知识成长体系 on SelfTechHub</title><link>https://blog.irudder.me/series/AI%E7%9F%A5%E8%AF%86%E6%88%90%E9%95%BF%E4%BD%93%E7%B3%BB.html</link><description>Recent content in AI知识成长体系 on SelfTechHub</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Thu, 30 Jul 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://blog.irudder.me/series/AI%E7%9F%A5%E8%AF%86%E6%88%90%E9%95%BF%E4%BD%93%E7%B3%BB/index.xml" rel="self" type="application/rss+xml"/><item><title>AI知识成长体系总纲——学习路径与进阶指南</title><link>https://blog.irudder.me/ai/ai-systematization/07-AI-Knowledge-Growth-System-Overview.html</link><pubDate>Thu, 30 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/ai-systematization/07-AI-Knowledge-Growth-System-Overview.html</guid><description>&lt;h1 id="ai知识成长体系总纲学习路径与进阶指南"&gt;AI知识成长体系总纲——学习路径与进阶指南
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;本文是「AI知识成长体系」系列的收官篇。前七篇文章已经把大模型工程的六大支柱——大模型基础、RAG、工具调用、LangChain框架、Agent、Claude Code——从原理到实践讲透了。这篇不再讲新技术，而是回答一个更重要的问题：&lt;strong&gt;怎么学、怎么练、怎么成长&lt;/strong&gt;。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一本文要回答的问题"&gt;一、本文要回答的问题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;作为一个想进入AI领域的工程师，应该按什么顺序学习？&lt;/li&gt;
&lt;li&gt;每个阶段应该掌握什么技能、做什么项目？&lt;/li&gt;
&lt;li&gt;怎么判断自己到了什么水平？下一个台阶是什么？&lt;/li&gt;
&lt;li&gt;面试高频考点是什么？怎么准备？&lt;/li&gt;
&lt;li&gt;AI技术迭代这么快，怎么持续跟进不掉队？&lt;/li&gt;
&lt;li&gt;不同岗位（后端/前端/数据/AI应用）的AI学习重点有什么不同？&lt;/li&gt;
&lt;li&gt;有哪些高质量的学习资源和社区？&lt;/li&gt;
&lt;li&gt;Claude Code等AI编程工具怎么学、怎么用？&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="二知识体系全景回顾"&gt;二、知识体系全景回顾
&lt;/h2&gt;&lt;p&gt;在讲学习路径之前，先用一张图回顾整套知识体系的结构和依赖关系：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌──────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ Claude Code实战 │ ← 前沿实践
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ (AI Coding Agent │ （工业级Agent最佳教材）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 源码/提示词/方法论) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──────────┬───────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 体现
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌──────────┴───────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ Agent智能体 │ ← 终极形态
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ (感知→规划→行动 │ （LLM+RAG+工具+记忆+反思）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ →反思 + Harness/Loop)│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──────────┬───────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 依赖
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌──────────┴───────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ LangChain框架 │ ← 工程化
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ (组件抽象+编排) │ （把组件标准化组合）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──────────┬───────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 依赖
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌────────────────┴────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────┴─────────┐ ┌──────────┴──────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ RAG检索增强生成 │ │ LLM工具调用 │ ← 能力层
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ (知识：外接知识库 │ │ (行动：调用外部工具) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ +GraphRAG) │ │ (FC→MCP→Skill) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────────┬─────────┘ └──────────┬──────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └────────────────┬────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 依赖
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌──────────┴───────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 大模型工程基础 │ ← 模型层
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ (Transformer/训练 │ （大脑本身）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ /推理/Prompt) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;核心逻辑&lt;/strong&gt;：从下往上，每一层都建立在前一层之上。地基不稳，上面的一切都是空中楼阁。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="三七级成长路径"&gt;三、七级成长路径
&lt;/h2&gt;&lt;p&gt;根据对大模型工程知识体系的理解，我们将AI工程师的成长路径划分为七级（新增Claude Code实战级），每一级都有明确的技能要求、实践项目和评估标准。&lt;/p&gt;
&lt;h3 id="level-0认知建立期0-2周"&gt;Level 0：认知建立期（0-2周）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：理解大模型是什么、能做什么、不能做什么，建立正确的认知框架。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;需要掌握的概念&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LLM的本质：预测下一个token的自回归生成模型&lt;/li&gt;
&lt;li&gt;大模型的三大局限：知识冻结、不能行动、没有持续状态&lt;/li&gt;
&lt;li&gt;AI工程的三个层次：模型层（大脑）→ 能力层（RAG+工具）→ 应用层（框架+Agent+Claude Code）&lt;/li&gt;
&lt;li&gt;RAG、Function Calling、Agent、MCP、Skill、CLAUDE.md这些术语的基本含义&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;推荐阅读&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本系列第00篇（导论）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;实践任务&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用ChatGPT/Claude/DeepSeek等工具完成5个不同类型的任务&lt;/li&gt;
&lt;li&gt;思考：哪些任务模型做得好？哪些做得差？为什么？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;评估标准&lt;/strong&gt;：能用自己的话解释「大模型是什么」「RAG解决什么问题」「Agent和聊天机器人有什么区别」「Claude Code是什么」。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="level-1基础理解期2-6周"&gt;Level 1：基础理解期（2-6周）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：理解大模型的底层原理，能看懂技术文档中的术语和概念。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;需要掌握的技能&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;知识模块&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;th&gt;优先级&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Transformer架构&lt;/td&gt;
&lt;td&gt;Self-Attention、Q/K/V、Encoder vs Decoder&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;训练三阶段&lt;/td&gt;
&lt;td&gt;预训练→SFT→对齐（RLHF/DPO）&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;推理优化&lt;/td&gt;
&lt;td&gt;KV Cache、量化、解码策略、Temperature/Top-p&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prompt工程&lt;/td&gt;
&lt;td&gt;Prompt五要素、CoT思维链&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;位置编码&lt;/td&gt;
&lt;td&gt;RoPE基本原理&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;分词器&lt;/td&gt;
&lt;td&gt;BPE算法&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;微调技术&lt;/td&gt;
&lt;td&gt;LoRA原理&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;部署框架&lt;/td&gt;
&lt;td&gt;vLLM/SGLang概念了解&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;推荐阅读&lt;/strong&gt;：本系列第01篇（完整阅读）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实践任务&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用Python调用OpenAI/Anthropic API，实现一个简单的对话程序&lt;/li&gt;
&lt;li&gt;实验不同的Temperature和Top-p参数，观察生成结果的差异&lt;/li&gt;
&lt;li&gt;写一个CoT Prompt，让模型解一道数学题&lt;/li&gt;
&lt;li&gt;用Ollama在本地运行开源模型&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;评估标准&lt;/strong&gt;：能解释Self-Attention原理、训练三阶段、KV Cache、Temperature参数。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="level-2rag实战期6-10周"&gt;Level 2：RAG实战期（6-10周）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：能独立构建一个RAG系统，理解从文档处理到检索生成的完整流程。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;需要掌握的技能&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;知识模块&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;th&gt;优先级&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RAG完整流程&lt;/td&gt;
&lt;td&gt;离线建库 + 在线检索生成&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;文档切割&lt;/td&gt;
&lt;td&gt;Chunking策略、chunk_size选择&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embedding&lt;/td&gt;
&lt;td&gt;原理、模型选型、评估&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;向量数据库&lt;/td&gt;
&lt;td&gt;Milvus/Chroma使用、HNSW索引&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;检索优化&lt;/td&gt;
&lt;td&gt;Query改写、多路召回、Rerank&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GraphRAG/LightRAG&lt;/td&gt;
&lt;td&gt;图增强RAG概念&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;效果评估&lt;/td&gt;
&lt;td&gt;Hit@K、RAGAs框架&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;推荐阅读&lt;/strong&gt;：本系列第02篇（完整阅读）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实践任务&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;构建一个个人知识库RAG系统&lt;/li&gt;
&lt;li&gt;实验不同的chunk_size（256/512/1024），对比检索效果&lt;/li&gt;
&lt;li&gt;对比纯向量检索 vs 向量+BM25混合检索&lt;/li&gt;
&lt;li&gt;加入Rerank步骤，观察精排效果&lt;/li&gt;
&lt;li&gt;用RAGAs框架评估RAG系统质量&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;评估标准&lt;/strong&gt;：能完整描述RAG离线+在线流程，解释文档切割的必要性，说出3种检索优化方法。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="level-3工具调用期10-14周"&gt;Level 3：工具调用期（10-14周）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：掌握Function Calling和MCP，能让LLM调用外部工具完成实际任务。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;需要掌握的技能&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;知识模块&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;th&gt;优先级&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Function Calling&lt;/td&gt;
&lt;td&gt;原理、schema定义、两轮对话流程&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;工具设计&lt;/td&gt;
&lt;td&gt;description编写、参数设计&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP协议&lt;/td&gt;
&lt;td&gt;架构、三类能力、Client-Server模型&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FC vs MCP&lt;/td&gt;
&lt;td&gt;区别、选型场景&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skill概念&lt;/td&gt;
&lt;td&gt;操作手册层、三层架构&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A2A协议&lt;/td&gt;
&lt;td&gt;Agent间协作&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLM网关&lt;/td&gt;
&lt;td&gt;统一管理概念&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;推荐阅读&lt;/strong&gt;：本系列第03篇（完整阅读）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实践任务&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用Function Calling实现一个天气查询+计算器工具&lt;/li&gt;
&lt;li&gt;实现并行工具调用&lt;/li&gt;
&lt;li&gt;搭建一个简单的MCP Server&lt;/li&gt;
&lt;li&gt;实现「模型决定不调工具」的场景&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;评估标准&lt;/strong&gt;：能解释FC三角色分工、MCP架构、FC/MCP/Skill三层架构。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="level-4框架应用期14-20周"&gt;Level 4：框架应用期（14-20周）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：熟练使用LangChain/LangGraph构建LLM应用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;需要掌握的技能&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;知识模块&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;th&gt;优先级&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LangChain核心组件&lt;/td&gt;
&lt;td&gt;Model I/O、Chains、Memory、Agents&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LCEL&lt;/td&gt;
&lt;td&gt;管道符语法、Runnable接口&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangGraph&lt;/td&gt;
&lt;td&gt;StateGraph、循环、分支、持久化&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;多Agent编排&lt;/td&gt;
&lt;td&gt;Supervisor/Network模式&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangSmith&lt;/td&gt;
&lt;td&gt;追踪、调试、评估&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;框架选型&lt;/td&gt;
&lt;td&gt;LangChain vs LlamaIndex vs 手搓&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;推荐阅读&lt;/strong&gt;：本系列第04篇（完整阅读）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实践任务&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用LangChain + LCEL构建RAG应用&lt;/li&gt;
&lt;li&gt;用LangGraph构建ReAct Agent&lt;/li&gt;
&lt;li&gt;用LangGraph实现简单的多Agent系统&lt;/li&gt;
&lt;li&gt;接入LangSmith进行追踪调试&lt;/li&gt;
&lt;li&gt;对比框架实现 vs 手搓实现&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;评估标准&lt;/strong&gt;：能用LCEL写管道符链，用LangGraph构建带循环的Agent，对比框架优劣。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="level-5agent架构师期20-28周"&gt;Level 5：Agent架构师期（20-28周）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：能设计完整的Agent系统，理解多Agent协作、Harness Engineering和Loop Engineering。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;需要掌握的技能&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;知识模块&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;th&gt;优先级&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent设计范式&lt;/td&gt;
&lt;td&gt;ReAct/Plan-and-Execute/Reflection选型&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;记忆机制&lt;/td&gt;
&lt;td&gt;短期/长期记忆、记忆压缩&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;任务拆分&lt;/td&gt;
&lt;td&gt;策略、并行优化&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;多Agent系统&lt;/td&gt;
&lt;td&gt;通信、路由、协作模式&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Harness Engineering&lt;/td&gt;
&lt;td&gt;Agent越用越聪明的工程方法&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loop Engineering&lt;/td&gt;
&lt;td&gt;从Prompt到Loop的范式转变&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;手搓vs框架&lt;/td&gt;
&lt;td&gt;什么时候该手搓&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenClaw&lt;/td&gt;
&lt;td&gt;开源Agent方法论&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;推荐阅读&lt;/strong&gt;：本系列第05篇（完整阅读）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实践任务&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;设计并实现一个完整的Agent系统（代码审查/客服/数据分析）&lt;/li&gt;
&lt;li&gt;实现三种设计范式各一个Demo，对比效果和token消耗&lt;/li&gt;
&lt;li&gt;设计多Agent协作系统（Writer+Reviewer+Editor）&lt;/li&gt;
&lt;li&gt;实现记忆压缩机制&lt;/li&gt;
&lt;li&gt;践行Harness Engineering：持续优化一个Agent的外围框架&lt;/li&gt;
&lt;li&gt;尝试Loop Engineering：用SDD+grill-me方式完成一个项目&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;评估标准&lt;/strong&gt;：能对比三种范式优劣，设计四层记忆机制，解释Harness/Loop Engineering，完成完整Agent项目。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="level-6ai编程实战期28周"&gt;Level 6：AI编程实战期（28周+）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：深入理解Claude Code等AI编程工具的架构，掌握AI编程方法论。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;需要掌握的技能&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;知识模块&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;th&gt;优先级&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code基础&lt;/td&gt;
&lt;td&gt;使用技巧、命令、交互模式&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLAUDE.md&lt;/td&gt;
&lt;td&gt;项目记忆工程、最佳实践&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skill机制&lt;/td&gt;
&lt;td&gt;编写、加载、渐进式披露&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDD&lt;/td&gt;
&lt;td&gt;规约驱动开发&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;grill-me&lt;/td&gt;
&lt;td&gt;需求审问方法论&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;源码架构&lt;/td&gt;
&lt;td&gt;Query Loop/Compact/grep/Memory/SubAgent&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;系统提示词&lt;/td&gt;
&lt;td&gt;Fable 5设计哲学&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI编程方法论&lt;/td&gt;
&lt;td&gt;expertise over coding&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;推荐阅读&lt;/strong&gt;：本系列第06篇（完整阅读）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实践任务&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用Claude Code完成一个真实项目，写好CLAUDE.md&lt;/li&gt;
&lt;li&gt;编写3-5个自定义Skill&lt;/li&gt;
&lt;li&gt;用SDD方式开发一个功能模块&lt;/li&gt;
&lt;li&gt;用grill-me方式审问一个复杂需求&lt;/li&gt;
&lt;li&gt;阅读Claude Code源码的Query Loop部分&lt;/li&gt;
&lt;li&gt;分析Fable 5系统提示词的设计模式&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;评估标准&lt;/strong&gt;：能解释CLAUDE.md的作用和写法、Skill机制、Compact压缩原理、为什么用grep不用RAG、SubAgent隔离机制。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="四不同岗位的ai学习重点"&gt;四、不同岗位的AI学习重点
&lt;/h2&gt;&lt;h3 id="后端工程师"&gt;后端工程师
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;重点学习路径：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00 → 01（快速浏览原理）→ 02（RAG重点）→ 03（工具调用，API设计）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 04（LangChain）→ 06（Claude Code，编程提效）→ 05（Agent概念）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;核心加分项：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- RAG系统工程化（高并发检索、缓存、分布式向量数据库）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- LLM网关设计与实现
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Agent系统后端架构（任务队列、状态管理、容错重试）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 模型部署与服务化（vLLM/Triton）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Claude Code的Skill和CLAUDE.md工程化
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="前端工程师"&gt;前端工程师
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;重点学习路径：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00 → 01（了解概念）→ 02（RAG流程理解）→ 04（LangChain，关注前端交互）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 06（Claude Code，AI编程）→ 05（Agent UX设计）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;核心加分项：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- LLM应用流式输出与前端渲染
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Agent对话界面交互设计
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 可视化Agent工作流编排（类似Dify/Coze）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 用Claude Code提高前端开发效率
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="数据工程师"&gt;数据工程师
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;重点学习路径：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00 → 01（Transformer/训练原理重点）→ 02（RAG重点，数据处理是核心）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 03（工具调用，数据查询Agent）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;核心加分项：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- RAG数据管道设计（ETL→清洗→切割→Embedding→入库）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 大规模向量数据处理与索引优化
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Embedding模型评估与选型
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- GraphRAG知识图谱构建
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="ai应用工程师"&gt;AI应用工程师
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;重点学习路径：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;全部8篇完整阅读，无捷径。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;核心加分项：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 全链路理解：从模型原理到Agent架构到Claude Code源码
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 能独立设计Agent系统架构
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 能做技术选型（模型/框架/向量数据库/部署方案）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Harness Engineering实践能力
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Loop Engineering方法论落地
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="五面试高频考点速查"&gt;五、面试高频考点速查
&lt;/h2&gt;&lt;h3 id="大模型工程出现频率"&gt;大模型工程（出现频率：★★★★★）
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;考点&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;th&gt;难度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Transformer架构&lt;/td&gt;
&lt;td&gt;Self-Attention公式、Q/K/V、为什么除√d_k&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;训练三阶段&lt;/td&gt;
&lt;td&gt;预训练/SFT/对齐分别做什么&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KV Cache&lt;/td&gt;
&lt;td&gt;原理、为什么能加速&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LoRA&lt;/td&gt;
&lt;td&gt;原理、为什么低秩有效&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;幻觉&lt;/td&gt;
&lt;td&gt;根因、能不能消除&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MoE&lt;/td&gt;
&lt;td&gt;总参数vs激活参数&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaling Law&lt;/td&gt;
&lt;td&gt;Chinchilla比例&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="rag出现频率"&gt;RAG（出现频率：★★★★☆）
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;考点&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;th&gt;难度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RAG完整流程&lt;/td&gt;
&lt;td&gt;离线+在线全流程&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAG vs 微调&lt;/td&gt;
&lt;td&gt;优劣势对比&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chunking策略&lt;/td&gt;
&lt;td&gt;怎么切、chunk_size怎么选&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;检索优化&lt;/td&gt;
&lt;td&gt;Query改写/多路召回/Rerank&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GraphRAG/LightRAG&lt;/td&gt;
&lt;td&gt;原理与选型&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="工具调用出现频率"&gt;工具调用（出现频率：★★★★☆）
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;考点&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;th&gt;难度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Function Calling原理&lt;/td&gt;
&lt;td&gt;两轮对话流程&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP是什么&lt;/td&gt;
&lt;td&gt;核心架构、三类能力&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP vs FC&lt;/td&gt;
&lt;td&gt;区别、选型&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FC/Skill/MCP三层&lt;/td&gt;
&lt;td&gt;职责边界&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="agent出现频率"&gt;Agent（出现频率：★★★★★）
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;考点&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;th&gt;难度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent vs LLM&lt;/td&gt;
&lt;td&gt;本质区别&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ReAct&lt;/td&gt;
&lt;td&gt;原理、循环流程&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;三种范式对比&lt;/td&gt;
&lt;td&gt;ReAct/Plan-Execute/Reflection&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;记忆机制&lt;/td&gt;
&lt;td&gt;短期/长期、压缩方法&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-Agent&lt;/td&gt;
&lt;td&gt;通信方式、路由&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Harness Engineering&lt;/td&gt;
&lt;td&gt;是什么、怎么做&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;手搓vs框架&lt;/td&gt;
&lt;td&gt;为什么手搓&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="claude-code出现频率新兴考点"&gt;Claude Code（出现频率：★★★☆☆，新兴考点）
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;考点&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;th&gt;难度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CLAUDE.md&lt;/td&gt;
&lt;td&gt;作用、怎么写&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skill机制&lt;/td&gt;
&lt;td&gt;是什么、怎么用&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compact压缩&lt;/td&gt;
&lt;td&gt;原理&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;grep vs RAG&lt;/td&gt;
&lt;td&gt;为什么不用RAG&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SubAgent&lt;/td&gt;
&lt;td&gt;隔离机制&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="六高质量学习资源推荐"&gt;六、高质量学习资源推荐
&lt;/h2&gt;&lt;h3 id="系统课程"&gt;系统课程
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;资源&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;适合阶段&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;本系列8篇文章&lt;/td&gt;
&lt;td&gt;教程&lt;/td&gt;
&lt;td&gt;Level 0-6&lt;/td&gt;
&lt;td&gt;你正在读的这套&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;吴恩达《ChatGPT Prompt Engineering》&lt;/td&gt;
&lt;td&gt;视频课&lt;/td&gt;
&lt;td&gt;Level 1&lt;/td&gt;
&lt;td&gt;Prompt工程入门&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;吴恩达《Building Systems with ChatGPT API》&lt;/td&gt;
&lt;td&gt;视频课&lt;/td&gt;
&lt;td&gt;Level 1-2&lt;/td&gt;
&lt;td&gt;LLM应用构建&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;吴恩达《LangChain for LLM App Dev》&lt;/td&gt;
&lt;td&gt;视频课&lt;/td&gt;
&lt;td&gt;Level 4&lt;/td&gt;
&lt;td&gt;LangChain入门&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;李宏毅《机器学习2024/2025》&lt;/td&gt;
&lt;td&gt;视频课&lt;/td&gt;
&lt;td&gt;Level 1&lt;/td&gt;
&lt;td&gt;Transformer/LLM原理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeepLearning.AI《Functions, Tools and Agents》&lt;/td&gt;
&lt;td&gt;视频课&lt;/td&gt;
&lt;td&gt;Level 3-4&lt;/td&gt;
&lt;td&gt;工具调用与Agent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="官方文档"&gt;官方文档
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;文档&lt;/th&gt;
&lt;th&gt;适合阶段&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI API文档&lt;/td&gt;
&lt;td&gt;Level 1+&lt;/td&gt;
&lt;td&gt;Function Calling参考&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic API文档&lt;/td&gt;
&lt;td&gt;Level 1+&lt;/td&gt;
&lt;td&gt;Claude系列，Tool Use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangChain官方文档&lt;/td&gt;
&lt;td&gt;Level 4+&lt;/td&gt;
&lt;td&gt;最权威的LangChain参考&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangGraph文档&lt;/td&gt;
&lt;td&gt;Level 4+&lt;/td&gt;
&lt;td&gt;多Agent编排&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP协议规范&lt;/td&gt;
&lt;td&gt;Level 3+&lt;/td&gt;
&lt;td&gt;MCP官方规范&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code文档&lt;/td&gt;
&lt;td&gt;Level 6+&lt;/td&gt;
&lt;td&gt;AI编程工具官方文档&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="开源项目"&gt;开源项目
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;适合阶段&lt;/th&gt;
&lt;th&gt;学什么&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LangChain&lt;/td&gt;
&lt;td&gt;Level 4+&lt;/td&gt;
&lt;td&gt;LLM应用框架设计&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangGraph&lt;/td&gt;
&lt;td&gt;Level 4+&lt;/td&gt;
&lt;td&gt;图式Agent编排&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AutoGen (Microsoft)&lt;/td&gt;
&lt;td&gt;Level 5&lt;/td&gt;
&lt;td&gt;多Agent对话框架&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CrewAI&lt;/td&gt;
&lt;td&gt;Level 5&lt;/td&gt;
&lt;td&gt;角色扮演多Agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LlamaIndex&lt;/td&gt;
&lt;td&gt;Level 2+&lt;/td&gt;
&lt;td&gt;RAG框架设计&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dify&lt;/td&gt;
&lt;td&gt;Level 4+&lt;/td&gt;
&lt;td&gt;LLM应用平台&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LightRAG&lt;/td&gt;
&lt;td&gt;Level 2+&lt;/td&gt;
&lt;td&gt;轻量级GraphRAG实现&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="社区与资讯"&gt;社区与资讯
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;社区&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hugging Face&lt;/td&gt;
&lt;td&gt;模型/数据集&lt;/td&gt;
&lt;td&gt;开源模型中心&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Papers with Code&lt;/td&gt;
&lt;td&gt;论文+代码&lt;/td&gt;
&lt;td&gt;前沿论文追踪&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;小林面试笔记&lt;/td&gt;
&lt;td&gt;面试&lt;/td&gt;
&lt;td&gt;本系列素材来源&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangChain Discord&lt;/td&gt;
&lt;td&gt;社区&lt;/td&gt;
&lt;td&gt;LangChain官方社区&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="七持续成长策略"&gt;七、持续成长策略
&lt;/h2&gt;&lt;h3 id="1-建立信息源"&gt;1. 建立信息源
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;关注关键实验室博客：OpenAI Blog、Anthropic Blog、Google DeepMind Blog&lt;/li&gt;
&lt;li&gt;关注关键会议：NeurIPS、ICML、ACL、ICLR&lt;/li&gt;
&lt;li&gt;关注关键人物：Andrej Karpathy、Harrison Chase（LangChain创始人）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-动手优先"&gt;2. 动手优先
&lt;/h3&gt;&lt;p&gt;看10篇文章不如跑1次代码。每学一个新概念，立刻写最小可运行示例。&lt;/p&gt;
&lt;h3 id="3-以项目驱动学习"&gt;3. 以项目驱动学习
&lt;/h3&gt;&lt;p&gt;推荐的项目难度递进：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;入门级&lt;/strong&gt;：个人知识库RAG（Level 2）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;进阶级&lt;/strong&gt;：带工具调用的Agent助手（Level 3-4）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;挑战级&lt;/strong&gt;：多Agent协作系统（Level 5）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;终极&lt;/strong&gt;：用Claude Code完成完整AI产品（Level 6）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4-建立知识图谱"&gt;4. 建立知识图谱
&lt;/h3&gt;&lt;p&gt;每学一个新东西，问自己：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个概念属于哪个知识分支？&lt;/li&gt;
&lt;li&gt;它和已学过的什么概念有关联？&lt;/li&gt;
&lt;li&gt;它替代/补充/颠覆了什么旧方法？&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="5-教是最好的学"&gt;5. 教是最好的学
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;写博客/笔记&lt;/li&gt;
&lt;li&gt;给同事做技术分享&lt;/li&gt;
&lt;li&gt;回答社区问题&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="八常见学习陷阱"&gt;八、常见学习陷阱
&lt;/h2&gt;&lt;h3 id="陷阱1跳过基础直接学框架"&gt;陷阱1：跳过基础直接学框架
&lt;/h3&gt;&lt;p&gt;不懂Transformer、不懂Embedding原理，直接学LangChain和Agent。结果遇到问题完全不知道怎么排查。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对策&lt;/strong&gt;：至少完成Level 1再碰框架。&lt;/p&gt;
&lt;h3 id="陷阱2只看不练"&gt;陷阱2：只看不练
&lt;/h3&gt;&lt;p&gt;看了一堆教程觉得「都懂了」，一动手就卡壳。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对策&lt;/strong&gt;：每学一个概念必须写代码验证。&lt;/p&gt;
&lt;h3 id="陷阱3追新成瘾"&gt;陷阱3：追新成瘾
&lt;/h3&gt;&lt;p&gt;AI领域每天都有新论文新框架，但底层原理（Transformer、Attention、RAG流程）非常稳定。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对策&lt;/strong&gt;：80%精力掌握稳定底层，20%精力跟进新动态。&lt;/p&gt;
&lt;h3 id="陷阱4忽视评估"&gt;陷阱4：忽视评估
&lt;/h3&gt;&lt;p&gt;做了Demo觉得效果「看起来还行」，到生产环境才发现检索准确率只有40%。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对策&lt;/strong&gt;：从Level 2开始建立评估意识。&lt;/p&gt;
&lt;h3 id="陷阱5不会用ai编程工具"&gt;陷阱5：不会用AI编程工具
&lt;/h3&gt;&lt;p&gt;很多人还在用传统方式写代码，不知道Claude Code等工具能把效率提升数倍。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对策&lt;/strong&gt;：尽早进入Level 6，学会用CLAUDE.md、Skill、SDD、grill-me。&lt;/p&gt;
&lt;h3 id="陷阱6忽视harness-engineering"&gt;陷阱6：忽视Harness Engineering
&lt;/h3&gt;&lt;p&gt;把Agent当一次性工具用，不做持续优化。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对策&lt;/strong&gt;：践行Harness Engineering，把Agent当系统持续打磨。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="九本系列知识体系总结"&gt;九、本系列知识体系总结
&lt;/h2&gt;&lt;p&gt;回顾全系列8篇文章：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;篇目&lt;/th&gt;
&lt;th&gt;标题&lt;/th&gt;
&lt;th&gt;核心价值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;00&lt;/td&gt;
&lt;td&gt;AI大模型工程知识体系总览与导论&lt;/td&gt;
&lt;td&gt;建立认知框架，找到学习路径&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;01&lt;/td&gt;
&lt;td&gt;大模型基础与工程化实践&lt;/td&gt;
&lt;td&gt;理解LLM本质，从Transformer到部署评测&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;02&lt;/td&gt;
&lt;td&gt;RAG检索增强生成——从原理到工程落地&lt;/td&gt;
&lt;td&gt;掌握企业AI落地最成熟的应用模式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;03&lt;/td&gt;
&lt;td&gt;LLM工具调用深度解析——从Function Calling到MCP&lt;/td&gt;
&lt;td&gt;让LLM从「说话」变成「做事」&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;04&lt;/td&gt;
&lt;td&gt;LangChain框架全解析——架构、组件与实战&lt;/td&gt;
&lt;td&gt;掌握LLM应用开发的标准框架&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;05&lt;/td&gt;
&lt;td&gt;Agent智能体——从概念到自主推理与行动&lt;/td&gt;
&lt;td&gt;理解AI工程的终极形态+Harness/Loop Engineering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;06&lt;/td&gt;
&lt;td&gt;Claude Code实战——AI编程工程深度拆解&lt;/td&gt;
&lt;td&gt;工业级Agent最佳实践教材&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;07&lt;/td&gt;
&lt;td&gt;本文：AI知识成长体系总纲&lt;/td&gt;
&lt;td&gt;系统化学习路径与持续成长策略&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="贯穿全系列的核心认知"&gt;贯穿全系列的核心认知
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;模型是大脑，代码是身体&lt;/strong&gt;：LLM永远是决策者，代码是执行者&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;知识在数据里，不在参数里&lt;/strong&gt;：RAG比微调更灵活&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;复杂任务必须拆分&lt;/strong&gt;：从文档切割到SubAgent&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;检索质量决定生成质量&lt;/strong&gt;：RAG的功夫在检索，但场景决定检索方式&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;记忆是Agent的连续性&lt;/strong&gt;：CLAUDE.md文件比向量数据库更适合代码项目&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;反思让Agent从错误中学习&lt;/strong&gt;：grill-me把反思前置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;框架是加速器，不是依赖&lt;/strong&gt;：Claude Code自己手搓了所有机制&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;评估是工程化的前提&lt;/strong&gt;：40万次会话研究驱动了方法论的诞生&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Harness Engineering让Agent越用越聪明&lt;/strong&gt;：优化外围框架比换模型更有效&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;从Prompt到Loop是范式转变&lt;/strong&gt;：AI编程重新定义了人机协作&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="十结语"&gt;十、结语
&lt;/h2&gt;&lt;p&gt;AI工程不是一个可以速成的领域，但它也并非高不可攀。关键在于：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;按正确的顺序学&lt;/strong&gt;：先原理后应用，先基础后框架&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动手实践&lt;/strong&gt;：每学一个概念就写代码&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;建立体系&lt;/strong&gt;：把碎片知识串联成知识树&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;持续迭代&lt;/strong&gt;：AI在演进，你的知识也要迭代&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用好AI工具&lt;/strong&gt;：用Claude Code等工具加速你的学习和开发&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;本系列文章提供了一个完整的知识框架和学习路径，但真正的成长发生在你合上这份文档、打开编辑器、开始写代码的那一刻。&lt;/p&gt;
&lt;p&gt;祝你在AI时代不掉队，甚至走在前面。&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;全系列完。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;本系列共8篇文章，覆盖大模型基础、RAG、工具调用、LangChain框架、Agent智能体、Claude Code实战六大核心主题，形成完整的AI知识成长体系。&lt;/p&gt;
&lt;p&gt;素材来源：小林面试笔记（xiaolinnote.com）七大板块共97篇深度文章，经带cookie完整抓取、系统性遍历、深度提取、改写重构而成。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;本文是「AI知识成长体系」系列第07篇（收官篇）。&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Claude Code实战——AI编程工程深度拆解</title><link>https://blog.irudder.me/ai/ai-systematization/06-Claude-Code-Practical-Guide.html</link><pubDate>Wed, 29 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/ai-systematization/06-Claude-Code-Practical-Guide.html</guid><description>&lt;h1 id="claude-code-实战ai-编程工程深度拆解"&gt;Claude Code 实战——AI 编程工程深度拆解
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;本文是「AI 大模型工程知识体系」系列的第 06 篇。在前五篇中，我们分别拆解了大模型原理、RAG 检索增强、工具调用机制和 LangChain 框架。本篇将视角从「通用 AI 工程」收束到当下最成功的 AI 编程实践——Claude Code，从基础使用到源码架构，做一次完整的工程深度拆解。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Claude Code 是 Anthropic 推出的命令行 AI 编程工具，它不是一个套壳的聊天机器人，而是一个能自主读代码、写代码、跑测试、做代码审查的智能体（Agent）。在 GitHub 上被无数开发者验证为「最好用的 AI 编程工具之一」。&lt;/p&gt;
&lt;p&gt;但本文不只是教你怎么用 Claude Code。我们将从三个层次展开：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;使用层&lt;/strong&gt;：基础操作、CLAUDE.md 配置、Skill 机制、SDD 方法论&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;架构层&lt;/strong&gt;：四层架构、Query Loop 主循环、上下文压缩、记忆系统&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;哲学层&lt;/strong&gt;：系统提示词设计、代码检索为何不用 RAG、多 Agent 协作、AI 编程的本质&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;读完本文，你不仅能把 Claude Code 用到极致，还能理解「一个工业级 AI Agent 是怎么设计出来的」。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第一章-基础使用与工作模式"&gt;第一章 基础使用与工作模式
&lt;/h2&gt;&lt;h3 id="11-四个工作模式"&gt;1.1 四个工作模式
&lt;/h3&gt;&lt;p&gt;启动 Claude Code 只需在终端敲一个 &lt;code&gt;claude&lt;/code&gt;。但真正决定它「怎么干活」的，是工作模式。Claude Code 有四个核心模式，用 &lt;code&gt;Shift+Tab&lt;/code&gt; 循环切换：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;行为&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Normal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;每次修改前征求你同意&lt;/td&gt;
&lt;td&gt;探索阶段、不熟悉的代码库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auto-accept edits&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;自动接受文件编辑，不再逐个确认&lt;/td&gt;
&lt;td&gt;信任方向、批量修改&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Plan Mode&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;只读探索不执行任何修改，先出方案&lt;/td&gt;
&lt;td&gt;复杂任务、需要先对齐思路&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom / Full Auto&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;自动执行所有操作（含命令）&lt;/td&gt;
&lt;td&gt;高度信任的重复性任务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Plan Mode 是最值得单独拎出来讲的。当你面对一个复杂需求——比如「重构整个认证模块」——直接让 AI 开干风险极大。Plan Mode 下，Claude Code 会进入只读探索状态：它可以 grep、可以读文件，但绝不写文件、不跑命令。它先把代码摸清楚，然后给你一份计划：改哪些文件、按什么顺序、预期效果是什么。你确认后，它再退出 Plan Mode 开始执行。&lt;/p&gt;
&lt;p&gt;这个设计背后的思想是：&lt;strong&gt;工具即能力&lt;/strong&gt;。Plan Mode 在源码层面是通过 &lt;code&gt;EnterPlanMode&lt;/code&gt; / &lt;code&gt;ExitPlanMode&lt;/code&gt; 两个工具实现的——模型调用 &lt;code&gt;EnterPlanMode&lt;/code&gt; 就进入只读状态，调用 &lt;code&gt;ExitPlanMode&lt;/code&gt; 时附带一份计划文本。不是靠什么复杂的状态机，就是把「能做什么」通过工具列表切了一下。&lt;/p&gt;
&lt;h3 id="12-十个官方进阶技能"&gt;1.2 十个官方进阶技能
&lt;/h3&gt;&lt;p&gt;Claude Code 提供了一套 &lt;code&gt;/powerup&lt;/code&gt; 课程体系，涵盖 10 个进阶能力。这里不逐条复述，而是按理解层次归类：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;引用与控制类：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@文件路径&lt;/code&gt; 引用文件，让模型直接读到内容&lt;/li&gt;
&lt;li&gt;&lt;code&gt;permissions.deny&lt;/code&gt; 配置屏蔽特定命令（比如禁止 &lt;code&gt;rm -rf&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Esc+Esc&lt;/code&gt; 撤销上一步操作——AI 改错了，一键回退&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;上下文管理类：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/context&lt;/code&gt; 查看当前上下文使用情况（用了多少 token）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/compact&lt;/code&gt; 手动压缩对话历史&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/clear&lt;/code&gt; 彻底清空对话重新开始&lt;/li&gt;
&lt;li&gt;&lt;code&gt;claude --resume&lt;/code&gt; / &lt;code&gt;--continue&lt;/code&gt; 恢复历史会话&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;扩展能力类：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CLAUDE.md&lt;/strong&gt;：项目级配置文件，每次启动自动加载（第二章详讲）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MCP&lt;/strong&gt;（Model Context Protocol）：通过 &lt;code&gt;claude mcp add&lt;/code&gt; 接入外部工具服务&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skills&lt;/strong&gt;：通过 &lt;code&gt;/plugin install&lt;/code&gt; 安装技能插件（第三章详讲）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hooks&lt;/strong&gt;：&lt;code&gt;PreToolUse&lt;/code&gt; / &lt;code&gt;PostToolUse&lt;/code&gt; 钩子，在工具执行前后插入自定义逻辑&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;子代理（SubAgent）&lt;/strong&gt;：通过 &lt;code&gt;/agents&lt;/code&gt; 管理独立的子 Agent 实例（第七章详讲）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;模型控制类：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/model&lt;/code&gt; 切换模型（Opus / Sonnet / Haiku）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/effort&lt;/code&gt; 设置推理深度：&lt;code&gt;low&lt;/code&gt; → &lt;code&gt;medium&lt;/code&gt; → &lt;code&gt;high&lt;/code&gt; → &lt;code&gt;xhigh&lt;/code&gt; → &lt;code&gt;max&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ultrathink&lt;/code&gt; 关键词：临时把推理挡位拉到最高（新版唯一生效的关键词）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="13-子代理-vs-skills两套扩展机制的区别"&gt;1.3 子代理 vs Skills：两套扩展机制的区别
&lt;/h3&gt;&lt;p&gt;这是初学者最容易混淆的概念。两者都能「扩展 Claude Code 的能力」，但机制完全不同：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Skills（技能） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 在主对话上下文中加载一份 .md 指南 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 模型读完指南后，用主对话的工具去执行 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 共享主 agent 的上下文窗口 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 适合：领域知识、操作规范、验证流程 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ SubAgent（子代理） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 启动一个独立的 agent 实例 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 有自己独立的上下文窗口和工具池 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 跑完只把结论返回给主 agent │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 适合：大规模探索、隔离任务、并行调研 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;一句话区分：&lt;strong&gt;Skill 是给主 agent 看的说明书，SubAgent 是派出去的独立员工&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="实践要点"&gt;实践要点
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;新手从 Normal 模式开始&lt;/strong&gt;，确认 AI 的修改方向正确后再切 Auto-accept&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;复杂任务必走 Plan Mode&lt;/strong&gt;：先对齐再执行，避免跑偏后回不了头&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;ultrathink&lt;/code&gt; 不是万能的&lt;/strong&gt;：它只在需要深度推理的场景（架构设计、复杂 bug）才有价值，日常写代码用默认挡位即可&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/context&lt;/code&gt; 要勤看&lt;/strong&gt;：上下文用到 70% 以上就该 &lt;code&gt;/compact&lt;/code&gt; 了，别等自动触发&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skills 和 SubAgent 不是二选一&lt;/strong&gt;：Skill 负责教主 agent「怎么做」，SubAgent 负责「派出去做」，可以组合使用&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="第二章-claudemd给-agent-的入职手册"&gt;第二章 CLAUDE.md：给 Agent 的入职手册
&lt;/h2&gt;&lt;h3 id="21-claudemd-不是-readme"&gt;2.1 CLAUDE.md 不是 README
&lt;/h3&gt;&lt;p&gt;很多人把 CLAUDE.md 当成项目 README 来写，这是最大的误解。&lt;/p&gt;
&lt;p&gt;README 是给人看的，介绍项目是干什么的、怎么安装。CLAUDE.md 是给 Agent 看的，它每次启动都会自动加载这个文件。所以它的本质是：&lt;strong&gt;一份给 AI 的入职手册&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;你写给新员工的入职手册会写什么？不会写「我们公司是一家做电商的」（他面试时知道了），而是写「提交代码前必须跑 &lt;code&gt;npm test&lt;/code&gt;」「数据库迁移文件放在 &lt;code&gt;db/migrations/&lt;/code&gt; 下」「千万别动 &lt;code&gt;legacy/&lt;/code&gt; 目录的代码」。&lt;/p&gt;
&lt;p&gt;CLAUDE.md 同理。它应该写的是：Agent 在这个项目里干活需要遵守的规则。&lt;/p&gt;
&lt;h3 id="22-200-行黄金线"&gt;2.2 200 行黄金线
&lt;/h3&gt;&lt;p&gt;Anthropic 自己做过统计：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CLAUDE.md 行数&lt;/th&gt;
&lt;th&gt;模型遵守率&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;≤ 200 行&lt;/td&gt;
&lt;td&gt;92%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200-400 行&lt;/td&gt;
&lt;td&gt;70%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt; 400 行&lt;/td&gt;
&lt;td&gt;急剧下降&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;为什么？因为 LLM 存在「Lost in the Middle」现象——放在上下文中间位置的信息，模型注意力会下降。CLAUDE.md 越长，真正被模型「看到并遵守」的比例越低。&lt;/p&gt;
&lt;p&gt;如果 200 行不够写怎么办？&lt;strong&gt;模块化拆分&lt;/strong&gt;。把规则拆到 &lt;code&gt;.claude/rules/&lt;/code&gt; 目录下，每个文件用 YAML frontmatter 声明它只在特定路径下生效：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;前端规范&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;React + Tailwind 项目规范&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="nt"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;**/*.tsx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;**/*.jsx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="c"&gt;# 前端规范&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;- &lt;span class="l"&gt;组件用函数式，不用 class component&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;- &lt;span class="l"&gt;状态管理用 Zustand，不用 Redux&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;- &lt;span class="l"&gt;CSS 用 Tailwind utility class，不写自定义 CSS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样拆分后，遵守率能回升到 96%。因为模型只在编辑 &lt;code&gt;.tsx&lt;/code&gt; 文件时才加载前端规范，不会在后端代码里也塞一堆前端规则浪费 token。&lt;/p&gt;
&lt;h3 id="23-三类反面教材"&gt;2.3 三类反面教材
&lt;/h3&gt;&lt;p&gt;什么样的 CLAUDE.md 是差的？三类典型反例：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;复述型&lt;/strong&gt;——把项目结构、技术栈复述一遍：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# 本项目是一个 React + Node.js 全栈应用
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;前端用 React 18，后端用 Express...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;模型自己 grep 一下就知道的事，写进 CLAUDE.md 纯属浪费 token。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;愿望型&lt;/strong&gt;——写了但无法验证：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# 代码质量要求
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 写出优雅、高效的代码
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 遵循最佳实践
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;「优雅」「高效」是主观的，模型无法执行。不如写「函数不超过 50 行」「所有 API 响应时间 &amp;lt; 200ms」。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;术语表型&lt;/strong&gt;——把一堆名词解释塞进去：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# 术语表
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- SSR: Server-Side Rendering
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- CSR: Client-Side Rendering
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- ISR: Incremental Static Regeneration
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;模型本身就知道这些术语，不需要你教。&lt;/p&gt;
&lt;h3 id="24-四条写作原则"&gt;2.4 四条写作原则
&lt;/h3&gt;&lt;p&gt;好的 CLAUDE.md 遵循四条原则：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;短&lt;/strong&gt;：200 行以内，超了就拆&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;具体可验证&lt;/strong&gt;：写「提交前跑 &lt;code&gt;npm test&lt;/code&gt;」不写「确保质量」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;告诉为什么&lt;/strong&gt;：写「不要用 mock 测试，因为上季度 mock 通过了但 prod 挂了」——有了 Why，模型在边界情况能自己判断该不该破例&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;持续更新&lt;/strong&gt;：用 &lt;code&gt;/memory&lt;/code&gt; 命令维护，发现新的坑就加进去&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="25-分层架构"&gt;2.5 分层架构
&lt;/h3&gt;&lt;p&gt;CLAUDE.md 不止项目根目录一个，它有六个层级（按加载优先级从低到高）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Managed │ 系统级路径，管理员强制策略 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ User │ ~/.claude/CLAUDE.md，个人全局 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Project │ 项目根/CLAUDE.md，签入 git 共享 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Local │ CLAUDE.local.md，不签 git 个人用 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Auto │ 自动记忆目录，Agent 自动写入 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Team │ team/ 子目录，团队共享的 AI 偏好 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;六层叠加（不是覆盖），全部拼进 system prompt。此外还有两个机制：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;@include&lt;/code&gt; 指令&lt;/strong&gt;：类似 C 语言的 &lt;code&gt;#include&lt;/code&gt;，在 CLAUDE.md 里写 &lt;code&gt;@~/company/security-rules.md&lt;/code&gt;，加载时自动把那个文件内容拼进来，支持跨文件引用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;@AGENTS.md&lt;/code&gt;&lt;/strong&gt;：跨工具兼容，Cursor、Windsurf 等工具也读这个文件，实现一份配置多工具通用&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="26-六段式模板"&gt;2.6 六段式模板
&lt;/h3&gt;&lt;p&gt;如果你不知道从哪开始，用 &lt;code&gt;/init&lt;/code&gt; 命令让 Claude Code 自己生成一份初稿，然后按六段式模板维护：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. Overview — 一句话项目简介
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. Commands — 常用命令（build/test/lint/deploy）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. Architecture — 关键架构决策
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. Conventions — 编码约定（命名、目录、风格）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5. Hard Constraints — 硬约束（绝对不能做的事）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;6. Gotchas — 踩过的坑（最容易出错的地方）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中 &lt;strong&gt;Gotchas（坑点清单）是含金量最高的部分&lt;/strong&gt;。它是你用血泪换来的经验，也是模型最容易忽略的地方。&lt;/p&gt;
&lt;h3 id="实践要点-1"&gt;实践要点
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CLAUDE.md 是写给 Agent 的，不是写给人的&lt;/strong&gt;——每写一句都问自己「模型能执行吗？」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;200 行是红线&lt;/strong&gt;——超了就拆到 &lt;code&gt;.claude/rules/&lt;/code&gt;，用 &lt;code&gt;paths&lt;/code&gt; 条件按需加载&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;每条规则带上 Why&lt;/strong&gt;——让模型在边界情况能自主判断&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gotchas 优先写&lt;/strong&gt;——「别用 &lt;code&gt;==&lt;/code&gt; 比较 null」比「写高质量代码」有用一万倍&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用 &lt;code&gt;/init&lt;/code&gt; 起步，用 &lt;code&gt;/memory&lt;/code&gt; 维护&lt;/strong&gt;——不要手写初稿，让 Agent 先帮你生成&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="第三章-skill-机制与渐进式披露"&gt;第三章 Skill 机制与渐进式披露
&lt;/h2&gt;&lt;h3 id="31-skill-是文件夹不是文件"&gt;3.1 Skill 是文件夹不是文件
&lt;/h3&gt;&lt;p&gt;很多人以为 Skill 就是一个 Markdown 文件。不是。Skill 是一个&lt;strong&gt;文件夹&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;my-skill/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── SKILL.md ← 核心指南（必需）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── references/ ← 参考文档（按需读取）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── api-spec.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── migration-guide.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── scripts/ ← 可执行脚本
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── validate.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── assets/ ← 静态资源
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── template.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;SKILL.md 是入口，但它不是全部。references 目录存放详细文档，模型只在需要时才读取；scripts 存放可执行脚本，模型可以按需调用。&lt;/p&gt;
&lt;h3 id="32-渐进式披露progressive-disclosure"&gt;3.2 渐进式披露（Progressive Disclosure）
&lt;/h3&gt;&lt;p&gt;这是 Skill 机制最核心的设计理念。它的灵感来自 UI 设计中的 Progressive Disclosure——不要一次性把所有信息塞给用户，而是按需展开。&lt;/p&gt;
&lt;p&gt;在 Skill 机制中，它分三个层级：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;平时状态：只给 description 清单（占上下文预算的 1%）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 用户任务匹配到某个 skill
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;调用状态：加载完整 SKILL.md（几十到几百行）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ SKILL.md 里引用了 references/xxx.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;深入状态：按需读取参考文档（可能几千行）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;关键设计在于 &lt;strong&gt;description 字段&lt;/strong&gt;。每个 Skill 的 SKILL.md 开头有一段 YAML frontmatter：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;my-validation-skill&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;验证 API 响应是否符合 OpenAPI 规范。当用户需要检查
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; API 接口返回值、验证 Swagger 文档、测试接口合规性时使用。&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;注意：&lt;strong&gt;description 是触发条件，不是给人看的摘要&lt;/strong&gt;。它写的是「什么情况下应该激活这个 Skill」，用的是模型能匹配的语言。Anthropic 对 description 有一个 250 字符的限制，就是要逼你写精炼的触发条件，而不是写说明书。&lt;/p&gt;
&lt;h3 id="33-九类-skill-分类"&gt;3.3 九类 Skill 分类
&lt;/h3&gt;&lt;p&gt;Skill 不是无差别的「插件」，按用途可以分九类：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类别&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;th&gt;价值评级&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;验证类&lt;/td&gt;
&lt;td&gt;检查代码/配置是否符合规范&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐ 最高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;工作流类&lt;/td&gt;
&lt;td&gt;封装多步骤操作流程&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知识类&lt;/td&gt;
&lt;td&gt;注入领域专业知识&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;模板类&lt;/td&gt;
&lt;td&gt;提供代码/文档模板&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;转换类&lt;/td&gt;
&lt;td&gt;格式转换、代码迁移&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;分析类&lt;/td&gt;
&lt;td&gt;数据/代码分析&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;集成类&lt;/td&gt;
&lt;td&gt;对接外部系统&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;导航类&lt;/td&gt;
&lt;td&gt;帮助理解代码结构&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;调试类&lt;/td&gt;
&lt;td&gt;辅助调试排障&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;验证类 Skill 价值最高&lt;/strong&gt;，因为它做的是模型最容易偷懒的事——检查自己的输出是否合规。一个「提交前检查是否有 &lt;code&gt;console.log&lt;/code&gt; 残留」的 Skill，比十个「帮你写代码」的 Skill 都管用。&lt;/p&gt;
&lt;h3 id="34-坑点清单gotchasskill-的灵魂"&gt;3.4 坑点清单（Gotchas）：Skill 的灵魂
&lt;/h3&gt;&lt;p&gt;一个 Skill 的 SKILL.md 里，最值钱的不是使用说明，而是 &lt;strong&gt;Gotchas（坑点清单）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;为什么？因为模型读完文档就知道「怎么做」，但不知道「哪里容易出错」。Gotchas 就是把前人踩过的坑列出来，让模型提前避雷：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Gotchas
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; ⚠️ &lt;span class="sb"&gt;`JSON.parse`&lt;/span&gt; 不会报错但会返回 undefined（当输入是 &amp;#34;undefined&amp;#34; 字符串时）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; ⚠️ &lt;span class="sb"&gt;`Date.getTimezoneOffset()`&lt;/span&gt; 的正负号跟直觉相反
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; ⚠️ 这里的 &lt;span class="sb"&gt;`userId`&lt;/span&gt; 是字符串不是数字，直接用 === 比较会翻车
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; ⚠️ 测试数据库是共享的，跑完测试必须清理数据
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这些坑点，模型自己探索要踩好几轮才能发现，但写在 Skill 里它一次就避开了。&lt;/p&gt;
&lt;h3 id="35-高阶用法"&gt;3.5 高阶用法
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;记忆持久化&lt;/strong&gt;：Skill 可以用 &lt;code&gt;CLAUDE_PLUGIN_DATA&lt;/code&gt; 目录存数据，跨会话保持状态。比如一个「代码风格学习」Skill，可以记住你每次纠正的偏好，下次自动应用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;脚本封装&lt;/strong&gt;：复杂操作封装成 scripts/ 下的脚本，SKILL.md 里告诉模型「跑 &lt;code&gt;scripts/validate.sh&lt;/code&gt;」即可，不用让模型自己拼命令。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;临时 Hook&lt;/strong&gt;：有一种叫 &lt;code&gt;careful&lt;/code&gt; / &lt;code&gt;freeze&lt;/code&gt; 的 Skill，它临时修改工具权限——比如 &lt;code&gt;freeze&lt;/code&gt; Skill 激活后，禁止所有写操作，只允许读。适合在审查代码时使用。&lt;/p&gt;
&lt;h3 id="36-分发与演化"&gt;3.6 分发与演化
&lt;/h3&gt;&lt;p&gt;Skill 的分发有两种路径：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;代码仓库&lt;/strong&gt;：直接放在项目的 &lt;code&gt;.claude/skills/&lt;/code&gt; 目录，跟代码一起版本管理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plugin Marketplace&lt;/strong&gt;：通过 &lt;code&gt;/plugin install&lt;/code&gt; 安装社区 Skill&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一个 Skill 的自然演化路径是：&lt;strong&gt;沙盒测试 → 口碑传播 → 正式发布&lt;/strong&gt;。先在自己项目里用，验证有效后分享给团队，最后发布到社区。&lt;/p&gt;
&lt;h3 id="实践要点-2"&gt;实践要点
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;description 写触发条件不写摘要&lt;/strong&gt;——「当用户需要&amp;hellip;时使用」比「这是一个&amp;hellip;工具」有效得多&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gotchas 是 Skill 的灵魂&lt;/strong&gt;——没有坑点清单的 Skill 只是一半的 Skill&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;验证类 Skill 投入产出比最高&lt;/strong&gt;——优先写「检查类」而非「生成类」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;references/ 目录利用好渐进式披露&lt;/strong&gt;——详细文档放这里，SKILL.md 里只放入口指引&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不要一个 Skill 干太多事&lt;/strong&gt;——一个 Skill 只解决一类问题，description 才能匹配精准&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="第四章-sdd-规约驱动开发与-grill-me-方法论"&gt;第四章 SDD 规约驱动开发与 grill-me 方法论
&lt;/h2&gt;&lt;h3 id="41-vibe-coding-的问题"&gt;4.1 Vibe Coding 的问题
&lt;/h3&gt;&lt;p&gt;「Vibe Coding」是 Andrej Karpathy 提出的概念——凭感觉跟 AI 对话写代码，想到哪说到哪。这种方式在原型阶段很爽，但项目一旦长大，问题就来了：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;越改越乱&lt;/strong&gt;。今天让 AI 加个功能，明天让它改个 bug，后天让它重构。每次改都对，但改了二十次之后，代码变成了什么样子谁也说不清。AI 没有全局记忆，每次都是「基于当前代码做局部修改」，局部最优的堆叠不等于全局合理。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;缺对齐&lt;/strong&gt;。你脑子里的需求是 A，AI 理解成 B，做出来你发现是 C。你说「不对，重做」，它又从零开始，之前的成果全白费。&lt;/p&gt;
&lt;p&gt;SDD（Spec-Driven Development，规约驱动开发）就是来解决这个问题的。&lt;/p&gt;
&lt;h3 id="42-spec-kit-工具链"&gt;4.2 spec-kit 工具链
&lt;/h3&gt;&lt;p&gt;Anthropic 开源了一套叫 &lt;code&gt;spec-kit&lt;/code&gt; 的工具，把 SDD 落地成五个命令，对应五个阶段：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;speckit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;constitution&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;定宪法：项目的根本约束和原则&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;speckit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;谈需求：只说做什么，不说怎么做&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;speckit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;定技术：选什么技术栈、怎么架构&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;speckit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;拆活：把计划拆成可执行的任务清单&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;speckit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;implement&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;写代码：按任务清单逐个实现&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;此外还有两个兜底命令：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/speckit-clarify&lt;/code&gt;：当需求含糊时，主动追问澄清&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/speckit-analyze&lt;/code&gt;：一致性检查，看规约、计划、代码三者是否对齐&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="43-sdd-与瀑布流的本质区别"&gt;4.3 SDD 与瀑布流的本质区别
&lt;/h3&gt;&lt;p&gt;看到「先定需求→再定方案→再拆任务→最后写代码」，很多人会说：这不就是瀑布流吗？&lt;/p&gt;
&lt;p&gt;不是。关键区别在于：&lt;strong&gt;规约是活的，随时可改&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;瀑布流的文档是「签字盖章后不能改」的死文档。SDD 的规约是「随时可以回头改」的活文档。你在 implement 阶段发现 specify 写错了？没问题，回头改 specify，然后 plan 和 tasks 自动跟着调整。&lt;/p&gt;
&lt;p&gt;这更接近「设计树」的概念——软件工程泰斗 Fred Brooks 说过，设计是一棵树，上游决策不定死（留有调整空间），下游全是空中楼阁（没有基础）。SDD 的每个阶段就是树的一个层级，你可以回到任意一个节点重新分支。&lt;/p&gt;
&lt;h3 id="44-适用场景"&gt;4.4 适用场景
&lt;/h3&gt;&lt;p&gt;SDD 不是所有项目都需要。它最适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;长期维护项目&lt;/strong&gt;：今天写的代码三年后还要改，没有规约就是灾难&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多人协作项目&lt;/strong&gt;：规约是团队对齐的工具&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;复杂业务逻辑&lt;/strong&gt;：需求层次多、边界条件多&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一次性脚本&lt;/li&gt;
&lt;li&gt;快速原型验证&lt;/li&gt;
&lt;li&gt;个人玩具项目&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="45-grill-me往死里盘问"&gt;4.5 grill-me：往死里盘问
&lt;/h3&gt;&lt;p&gt;SDD 解决的是「怎么把需求讲清楚」，但在写规约之前，还有一步更前置的：&lt;strong&gt;你自己得先想清楚你要什么&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;grill-me&lt;/code&gt; 是一个社区 Skill，核心理念三句话：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;往死里盘问&lt;/strong&gt;：在开始写代码前，把需求里所有模糊的地方全问一遍&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一次只问一个&lt;/strong&gt;：不要一次抛十个问题，一次一个，问完再问下一个&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;能翻代码就别问&lt;/strong&gt;：能在代码里找到答案的，不要问用户&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;grill-me 最精妙的地方在于它跟 Plan Mode 的配合：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户提需求
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grill-me 模式启动：逐个追问模糊点
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ （通常 10-15 个问题，20-30 分钟）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;需求完全清晰
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Plan Mode：基于清晰需求出方案
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;执行
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="46-grill-me-vs-superpowers实测对比"&gt;4.6 grill-me vs superpowers：实测对比
&lt;/h3&gt;&lt;p&gt;社区里另一个流行的 Skill 叫 &lt;code&gt;superpowers&lt;/code&gt;，也是做需求澄清的。两者实测对比：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;grill-me&lt;/th&gt;
&lt;th&gt;superpowers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;问题数量&lt;/td&gt;
&lt;td&gt;12 个&lt;/td&gt;
&lt;td&gt;4 个&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;耗时&lt;/td&gt;
&lt;td&gt;32 分钟&lt;/td&gt;
&lt;td&gt;2 小时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;覆盖深度&lt;/td&gt;
&lt;td&gt;片纸不留&lt;/td&gt;
&lt;td&gt;留完整文档+测试+git&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;美术风格等主观项&lt;/td&gt;
&lt;td&gt;问用户拍板&lt;/td&gt;
&lt;td&gt;用默认值&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;最关键的差异在「美术风格」这类主观决策上。grill-me 会问「你要什么风格？」让你拍板；superpowers 直接用默认值。结果成品差距巨大——一个是你想要的，一个是它猜的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;建议：大多数人先装 grill-me&lt;/strong&gt;。superpowers 更适合需要自动生成测试和文档的场景，但它耗时长、问题少，容易漏掉关键需求点。&lt;/p&gt;
&lt;h3 id="实践要点-3"&gt;实践要点
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Vibe Coding 适合原型，SDD 适合产品&lt;/strong&gt;——项目要长期维护就上 SDD&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;spec-kit 五步不是瀑布流&lt;/strong&gt;——规约随时可改，这才是 SDD 和瀑布流的本质区别&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;grill-me 在 Plan Mode 之前跑&lt;/strong&gt;——先想清楚再出方案&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;grill-me 的「能翻代码就别问」原则&lt;/strong&gt;——减少用户负担，能用工具查的就自己查&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主观决策一定要让用户拍板&lt;/strong&gt;——AI 的默认审美不一定对&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="第五章-源码架构四层架构与-query-loop"&gt;第五章 源码架构：四层架构与 Query Loop
&lt;/h2&gt;&lt;h3 id="51-四层架构鸟瞰"&gt;5.1 四层架构鸟瞰
&lt;/h3&gt;&lt;p&gt;Claude Code 的源码（反编译后的 TypeScript）呈现出清晰的四层架构：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 安全与治理层 (Security &amp;amp; Governance) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 权限控制 · Hook 系统 · Bash 安全沙箱 · 工具三属性 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 服务层 (Services) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ API 客户端 · Prompt Cache · MCP Server · 压缩服务 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 工具层 (Tools) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 40+ 工具 · 每个工具强制三安全属性 · 流式执行器 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 引擎层 (Engine) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 协调 · 分发 · 决策（无业务逻辑，纯流程控制） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;引擎层是大脑，负责「下一步干什么」的决策；工具层是手脚，负责「具体怎么干」；服务层是基础设施，负责跟外部世界通信；安全层是免疫系统，贯穿所有层。&lt;/p&gt;
&lt;h3 id="52-tool-use-loop-vs-react"&gt;5.2 Tool-Use Loop vs ReAct
&lt;/h3&gt;&lt;p&gt;大多数 Agent 框架用的是 ReAct 模式：Thought（思考）→ Action（行动）→ Observation（观察）→ 循环。每一步都有显式的 Thought 步骤。&lt;/p&gt;
&lt;p&gt;Claude Code 不用 ReAct。它用的是 API 原生的 &lt;strong&gt;Tool-Use Loop&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Claude Code 的核心循环（简化版）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;call_llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="c1"&gt;# 模型说&amp;#34;我做完了&amp;#34;，循环结束&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tool_use&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;execute_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_use&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 把工具结果塞回对话历史&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;没有 Thought 步骤。模型的推理过程通过 Extended Thinking（扩展思考）在 API 内部完成，应用层看不到也不需要看到。应用层就是极简的 &lt;code&gt;while(true)&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这个设计的哲学是：&lt;strong&gt;信任模型的推理能力，应用层极简&lt;/strong&gt;。你不需要在应用层模拟模型的思考过程，模型自己会想。&lt;/p&gt;
&lt;p&gt;终止条件是 &lt;code&gt;end_turn&lt;/code&gt;——当模型认为任务完成时，它返回的 response 里不带 &lt;code&gt;tool_use&lt;/code&gt;，循环自然结束。Claude Code 定义了 &lt;strong&gt;17 种退出原因&lt;/strong&gt;，包括 &lt;code&gt;completed&lt;/code&gt;（正常完成）、&lt;code&gt;max_turns&lt;/code&gt;（超过最大轮数）、&lt;code&gt;aborted_streaming&lt;/code&gt;（流式中断）、&lt;code&gt;prompt_too_long&lt;/code&gt;（上下文超限）、&lt;code&gt;max_output_tokens_recovery&lt;/code&gt;（输出截断恢复中）等。&lt;/p&gt;
&lt;h3 id="53-query-loop-的四层调用链"&gt;5.3 Query Loop 的四层调用链
&lt;/h3&gt;&lt;p&gt;Claude Code 的主流程叫 Query Loop，它的调用链有四层：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ask() ← 用户入口
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └→ QueryEngine.submitMessage() ← 引擎层接收
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └→ query() ← 引擎层处理
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └→ queryLoop() ← 核心循环（async generator）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;全用 &lt;strong&gt;async generator&lt;/strong&gt;（异步生成器）实现，意思是「边干边吐」——模型还没说完，已经把前面的内容流式输出了。用户看到的是打字机效果，但底层是一条消息还没接收完，下一轮工具调用可能已经开始了。&lt;/p&gt;
&lt;h3 id="54-主循环五步"&gt;5.4 主循环五步
&lt;/h3&gt;&lt;p&gt;每一轮循环做五件事：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;①&lt;/span&gt; &lt;span class="err"&gt;准备消息&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;检查上下文是否需要被动压缩&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;②&lt;/span&gt; &lt;span class="err"&gt;流式调用模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="err"&gt;流式返回&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;③&lt;/span&gt; &lt;span class="err"&gt;判断终止条件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;有&lt;/span&gt; &lt;span class="n"&gt;tool_use&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;继续&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;end_turn&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;结束&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;④&lt;/span&gt; &lt;span class="err"&gt;执行工具&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;StreamingToolExecutor&lt;/span&gt; &lt;span class="err"&gt;并行启动只读工具&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;写操作串行执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;⑤&lt;/span&gt; &lt;span class="err"&gt;塞回结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;tool_result&lt;/span&gt; &lt;span class="err"&gt;注入对话历史&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;进入下一轮&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="55-streamingtoolexecutor边输出边执行"&gt;5.5 StreamingToolExecutor：边输出边执行
&lt;/h3&gt;&lt;p&gt;这是 Claude Code 架构里最精妙的设计之一。&lt;/p&gt;
&lt;p&gt;传统的做法是：等模型把整条 response 输出完 → 解析出所有 tool_use → 逐个执行。这样有延迟——模型说完了才开始干活。&lt;/p&gt;
&lt;p&gt;Claude Code 的 &lt;code&gt;StreamingToolExecutor&lt;/code&gt; 做的是：&lt;strong&gt;模型还在流式输出时，一旦检测到一个完整的 tool_use，立刻启动执行&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;但不是所有工具都能并行。规则是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;只读工具（Read、Grep、Glob）可以并行&lt;/strong&gt;——它们不改状态，同时跑不会冲突&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;写操作（Edit、Write、Bash）串行执行&lt;/strong&gt;——改文件这种事不能并发，否则会互相覆盖&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fail-closed 兜底&lt;/strong&gt;：如果并行执行出了问题，按最保守的策略处理（失败而不是继续）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="56-跨轮状态对象"&gt;5.6 跨轮状态对象
&lt;/h3&gt;&lt;p&gt;每轮循环之间，Claude Code 维护一个 State 对象：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;: &lt;span class="kt"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="c1"&gt;// 完整对话历史
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;turnCount&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 当前轮数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;maxOutputTokensRecoveryCount&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 输出截断恢复次数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;hasAttemptedReactiveCompact&lt;/span&gt;: &lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 是否已尝试被动压缩
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这些状态决定了循环的行为：轮数超限要退出、输出截断要恢复、上下文快满了要压缩。&lt;/p&gt;
&lt;h3 id="57-工具跑挂了怎么办"&gt;5.7 工具跑挂了怎么办
&lt;/h3&gt;&lt;p&gt;Agent 调一个工具，工具抛异常了，怎么办？最直觉的做法是抛给模型一个错误消息。但 Claude Code 的做法更细致：&lt;strong&gt;合成一个假的 tool_result（&lt;code&gt;is_error: true&lt;/code&gt;）塞回对话历史&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;为什么？因为 API 协议要求 tool_use 和 tool_result 必须配对。如果模型发了一个 tool_use 但没收到对应的 tool_result，下一轮 API 调用会直接报错。所以即使工具挂了，也必须塞一个「假」的 result 回去，告诉模型「这个工具失败了」，让模型自己决定下一步。&lt;/p&gt;
&lt;h3 id="58-输出截断恢复"&gt;5.8 输出截断恢复
&lt;/h3&gt;&lt;p&gt;有时候模型的输出太长，API 会截断。Claude Code 的恢复策略是：&lt;strong&gt;静默升档 + nudge 续写&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;输出被截断
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;静默升档：max_output_tokens 从 8K → 64K
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nudge 续写：发一条&amp;#34;请继续&amp;#34;的消息，让模型接着写
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ （最多重试 3 次）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;拼接完整输出
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;「静默」是指用户看不到这个过程，只看到最终结果。升档是调大 API 的 max_output_tokens 参数，nudge 是发一条特殊消息让模型继续未完成的输出。&lt;/p&gt;
&lt;h3 id="实践要点-4"&gt;实践要点
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Tool-Use Loop 的极简设计是核心理念&lt;/strong&gt;——不要在应用层模拟模型思考，信任模型&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;StreamingToolExecutor 的并行/串行规则值得借鉴&lt;/strong&gt;——只读并行、写操作串行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具失败要合成假 result&lt;/strong&gt;——API 协议要求 tool_use 和 tool_result 配对&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;17 种退出原因是工业级设计的体现&lt;/strong&gt;——不是简单的「成功/失败」二元判断&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;async generator 让用户体验更流畅&lt;/strong&gt;——边算边输出，别等算完再吐&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="第六章-上下文管理五层压缩金字塔"&gt;第六章 上下文管理：五层压缩金字塔
&lt;/h2&gt;&lt;h3 id="61-为什么上下文管理是-agent-的灵魂"&gt;6.1 为什么上下文管理是 Agent 的灵魂
&lt;/h3&gt;&lt;p&gt;LLM 是无状态的——每次调用都是从头看一遍所有消息。上下文窗口就是它能「看到」的最大范围。但窗口是有限的，Agent 跑着跑着就会塞满。&lt;/p&gt;
&lt;p&gt;大多数 Agent 框架的做法很粗糙：滑动窗口（保留最近 N 轮）、或者定期摘要（把旧消息压缩成一段）。Claude Code 的做法精细得多——它用了一个&lt;strong&gt;五层压缩金字塔&lt;/strong&gt;，每层解决不同的问题。&lt;/p&gt;
&lt;h3 id="62-五层压缩金字塔"&gt;6.2 五层压缩金字塔
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌───────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第5层 │ Auto-Compact│ 全量摘要重写（最后手段）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────┬─────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────┴─────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第4层 │Context Collapse│ 读时投影（不修改原始消息）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────┬─────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────┴─────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第3层 │Micro-Compact │ 时间衰减清旧工具结果
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────┬─────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────┴─────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第2层 │ Snip │ 砍远古消息（模型顺手标记）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────┬─────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────┴─────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第1层 │ Disk Cache │ 大结果存磁盘留预览
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └───────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;从底到顶，压缩力度递增，但每层都有独立的触发条件和适用场景。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 1 层：大结果存磁盘。&lt;/strong&gt; 当工具返回结果超过 50KB 时，不塞进对话历史，而是存到磁盘文件，只在对话里留一个 2KB 的预览。模型需要看完整内容时，可以 Read 那个磁盘文件。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 2 层：Snip（砍远古消息）。&lt;/strong&gt; 模型在正常对话过程中，会顺手标记一些「不再需要的旧消息」。这些消息被 Snip 机制移除，零额外 API 调用——因为标记是模型在正常推理时顺手做的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 3 层：Micro-Compact（时间衰减）。&lt;/strong&gt; 距离上次 API 调用超过 60 分钟的旧工具结果，内容被清空，只留元数据占位符。但保留最近 5 个工具结果不动。子 Agent 的输出不受此机制裁剪——因为子 Agent 输出是「结论」不是「过程」。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 4 层：Context Collapse（读时投影）。&lt;/strong&gt; 当上下文使用率达到 90% 或 95% 时触发。它的特点是&lt;strong&gt;不修改原始消息&lt;/strong&gt;——只是在「读取」时做投影，把中间的工具调用结果折叠掉，只保留摘要。原始消息还在，只是模型「看到」的是折叠版。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 5 层：Auto-Compact（全量摘要）。&lt;/strong&gt; 最后手段。当 token 数超过阈值（有效窗口 - 13K 缓冲）时触发。把所有历史消息送进摘要器，全量重写成一份结构化摘要。&lt;/p&gt;
&lt;p&gt;注意：&lt;strong&gt;Auto-Compact 和 Context Collapse 互斥&lt;/strong&gt;，同一时刻只会触发其中一个。&lt;/p&gt;
&lt;h3 id="63-auto-compact-的触发阈值"&gt;6.3 Auto-Compact 的触发阈值
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AUTOCOMPACT_BUFFER_TOKENS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getAutoCompactThreshold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;effectiveContextWindow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getEffectiveContextWindowSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;effectiveContextWindow&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;AUTOCOMPACT_BUFFER_TOKENS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里有个容易被忽略的细节：「有效上下文窗口」本身已经从原始窗口里扣掉了约 20K，专门留给摘要输出用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Based on p99.99 of compact summary output being 17,387 tokens.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MAX_OUTPUT_TOKENS_FOR_SUMMARY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Anthropic 跑了大规模数据统计，发现摘要输出的 p99.99 分位是 17,387 token。向上取整加冗余，凑成 20K。所以&lt;strong&gt;真正的缓冲是 20K + 13K ≈ 33K&lt;/strong&gt;，不是表面看到的 13K。&lt;/p&gt;
&lt;h3 id="64-全量重写反直觉的核心设计"&gt;6.4 全量重写：反直觉的核心设计
&lt;/h3&gt;&lt;p&gt;大多数 Agent 框架做压缩时，保留最近 N 轮，把前面的压成摘要。Claude Code 不这么做——它把&lt;strong&gt;所有 200 轮消息全部送进摘要器，重新写一份&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;第一眼看这设计很激进：最近的对话也不保留？那 Agent 不是丢了眼前正在做的事？&lt;/p&gt;
&lt;p&gt;不会。因为压缩后的消息不是只有一段摘要，而是&lt;strong&gt;四段式结构&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;buildPostCompactMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;: &lt;span class="kt"&gt;CompactionResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;boundaryMarker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// ① 压缩边界标记
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;summaryMessages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// ② 摘要消息
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attachments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// ③ 附件（文件、技能、计划等）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hookResults&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// ④ hook 执行结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;边界标记&lt;/strong&gt;：记录压缩是自动还是手动、压缩前 token 数、最后一条消息 ID&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;摘要消息&lt;/strong&gt;：200 轮全部压缩进这里&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;附件&lt;/strong&gt;：最近读过的文件、当前计划文件、激活的技能、异步任务状态&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;hook 结果&lt;/strong&gt;：用户配置的 hooks 在压缩时执行的结果&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关键在于：&lt;strong&gt;不同信息有不同的半衰期，走不同通道恢复&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;语义信息（「用户想给登录接口加验证码」「技术方案改成了 JWT」）→ 压成摘要&lt;/li&gt;
&lt;li&gt;状态信息（「a.py 第 42 行有 bug 在改」「文件读到第 100 行」）→ 走附件原样恢复&lt;/li&gt;
&lt;li&gt;永久指令（CLAUDE.md）→ 不进摘要，清空缓存让下一轮自动重新加载&lt;/li&gt;
&lt;li&gt;操作配置（system prompt、工具列表）→ 每次重建&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="65-文件恢复策略"&gt;6.5 文件恢复策略
&lt;/h3&gt;&lt;p&gt;压缩后，最多重新加载 5 个文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;POST_COMPACT_MAX_TOKENS_PER_FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt; &lt;span class="c1"&gt;// 每文件最多 5K token
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;POST_COMPACT_TOKEN_BUDGET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt; &lt;span class="c1"&gt;// 总预算 50K
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;POST_COMPACT_MAX_FILES_TO_RESTORE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;// 最多 5 个文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;按「最近活跃度」排，最近被 Read 过的优先。三个参数把「保留最近文件」这个模糊概念工程化定义死了。&lt;/p&gt;
&lt;h3 id="66-摘要-prompt两百多行的精巧设计"&gt;6.6 摘要 Prompt：两百多行的精巧设计
&lt;/h3&gt;&lt;p&gt;Claude Code 的摘要 Prompt 长达两百多行，光「禁止工具调用」这一条就重复了两次：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;CRITICAL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Respond&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;TEXT&lt;/span&gt; &lt;span class="n"&gt;ONLY&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Do&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Do&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Grep&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Glob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Edit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;ANY&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="k"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Tool&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;REJECTED&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;waste&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;turn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Your&lt;/span&gt; &lt;span class="n"&gt;entire&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="n"&gt;must&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;plain&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;为什么要夹着喊？因为早期 Sonnet 版本的模型经常无视一次警告，看到对话里提到「这个文件 Read 过」就手痒去 Read 一下。工程师们干脆「前后包夹」——开头喊一遍，结尾再喊一遍。&lt;/p&gt;
&lt;p&gt;摘要输出要求用 XML 格式，包含 &lt;strong&gt;9 个固定章节&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;analysis&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[模型推理草稿，最终被剥离]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/analysis&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. Primary Request and Intent — 主要请求和意图
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. Key Technical Concepts — 关键技术概念
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. Files and Code Sections — 涉及的文件和代码
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. Errors and fixes — 碰到的错误和修复
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5. Problem Solving — 解决的问题
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;6. All user messages — 所有用户消息（枚举！）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;7. Pending Tasks — 待办任务
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;8. Current Work — 当前进度（最细颗粒度！）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;9. Optional Next Step — 下一步建议
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第 6 项「所有用户消息」和第 8 项「当前进度」是灵魂：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 6 项&lt;/strong&gt;不是概括，是&lt;strong&gt;枚举&lt;/strong&gt;——用户在第 30 轮改了需求、第 80 轮提了新约束、第 150 轮说「放弃那个方向」，一个不能落&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 8 项&lt;/strong&gt;要精确到文件名和函数名——不是「正在调试」，而是「正在调试 auth.ts 的 refreshToken 函数，发现 cookie 过期判断有 bug」&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="67-熔断与递归守卫"&gt;6.7 熔断与递归守卫
&lt;/h3&gt;&lt;p&gt;Auto-Compact 有两个安全机制：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Circuit Breaker（断路器）&lt;/strong&gt;：连续失败 3 次就停止重试。源码注释说，曾经有 1000 多个会话因为反复压缩失败、不停重试，把 API 账单当烟花放。这种「带着血味儿的设计」是从生产环境里活下来的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;递归守卫&lt;/strong&gt;：摘要任务本身也是开了一个子 Agent 调模型，那它会不会因为消耗 token 又触发 auto-compact，进入死循环？&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;querySource&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;session_memory&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;querySource&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;compact&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="c1"&gt;// 不触发压缩
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;三行代码堵死了无限递归。&lt;/p&gt;
&lt;h3 id="68-压缩后怎么接续"&gt;6.8 压缩后怎么接续
&lt;/h3&gt;&lt;p&gt;摘要开头会被包装成一句话：「本会话是从之前一次因上下文耗尽而中断的对话延续过来的。以下摘要概述了之前的对话内容。」&lt;/p&gt;
&lt;p&gt;这句话很重要——它告诉模型「你是接力，不是从头开始」。模型看到后不会问「请问您想做什么」，而是顺着摘要的 Current Work 往下接。&lt;/p&gt;
&lt;p&gt;自动触发时还会打开 &lt;code&gt;suppressFollowUpQuestions&lt;/code&gt; 开关，禁止摘要器生成「需要进一步确认」的问题——因为在 agent 正在干活时触发压缩，不能让一个新问题打断节奏。&lt;/p&gt;
&lt;h3 id="实践要点-5"&gt;实践要点
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;五层金字塔是分层防御&lt;/strong&gt;——不要一上来就全量压缩，先用轻量手段&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全量重写比保留最近 N 轮更有效&lt;/strong&gt;——Lost in the Middle 让中间消息本来就看不清&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不同信息走不同通道&lt;/strong&gt;——语义进摘要、状态走附件、永久指令靠缓存重载&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;摘要 Prompt 要防呆&lt;/strong&gt;——「禁止工具调用」要前后包夹，模型真的会手痒&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Circuit Breaker 是生产环境的标配&lt;/strong&gt;——任何重试机制都要有熔断&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上下文管理不是省 token，是保信息结构&lt;/strong&gt;——这是 Claude Code 压缩哲学的核心&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="第七章-代码检索与记忆机制"&gt;第七章 代码检索与记忆机制
&lt;/h2&gt;&lt;h3 id="71-为什么不用-rag-检索代码"&gt;7.1 为什么不用 RAG 检索代码
&lt;/h3&gt;&lt;p&gt;这是面试 Claude Code 时常被问的问题：&lt;strong&gt;为什么不用 RAG 检索代码，而是用 grep？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;RAG（检索增强生成）是当下 AI 应用的标配——先给文档做 embedding 存进向量数据库，查询时算相似度召回 Top-K。但在代码场景下，RAG 有五个水土不服的痛点：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;痛点 1：代码切不动。&lt;/strong&gt; 文章是流式的，拦腰切一刀损失不大。但代码有严格结构——一个 200 行的函数按 100 行切，上半段是 &lt;code&gt;if&lt;/code&gt; 开头、下半段是 &lt;code&gt;else&lt;/code&gt; 结尾，两个片段都没法用。函数 A 调用函数 B，但它们在不同片段里，模型只看到 A 不知道 B 是什么。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;痛点 2：精确匹配做不了。&lt;/strong&gt; 向量召回是「找相似的」不是「找对的」。你说「找 &lt;code&gt;getUserById&lt;/code&gt;」，向量库返回 &lt;code&gt;getUserByName&lt;/code&gt;、&lt;code&gt;getUserByEmail&lt;/code&gt;、&lt;code&gt;fetchUserInfo&lt;/code&gt;——全是相似的，但没有一个是对的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;痛点 3：索引跟不上代码变化。&lt;/strong&gt; 开发者一个 commit 改了 20 个文件，索引怎么办？重建成本高、不重建用过期信息、增量更新边界情况多。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;痛点 4：冷启动慢。&lt;/strong&gt; 百万行代码库建索引要十几分钟，用户打开工具等进度条转？直接劝退。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;痛点 5：黑盒不可解释。&lt;/strong&gt; 向量召回回来 5 个片段，为什么是这 5 个？没人答得上。出了 bug 没法 debug。&lt;/p&gt;
&lt;h3 id="72-claude-code-的三件套"&gt;7.2 Claude Code 的三件套
&lt;/h3&gt;&lt;p&gt;Claude Code 的检索方案简单到让人意外：&lt;strong&gt;让模型像程序员一样，自己去找&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;三个工具，对应程序员的三步工作流：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;程序员工作流 Claude Code 工具
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;───────────── ──────────────
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;find（按文件名找） ←→ Glob（支持 **/*.tsx pattern）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -r（按内容搜） ←→ Grep（基于 ripgrep，Rust 写的）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat（看文件内容） ←→ Read（默认读 2000 行，可分段）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;每个工具都有精巧设计：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Grep&lt;/strong&gt; 底层是 ripgrep（Rust 写的），多线程并行、自动尊重 .gitignore。三种输出模式：&lt;code&gt;content&lt;/code&gt;（返回匹配行）、&lt;code&gt;files_with_matches&lt;/code&gt;（只返回文件名）、&lt;code&gt;count&lt;/code&gt;（只返回数量）。System Prompt 里强硬要求：「ALWAYS use Grep&amp;hellip; NEVER invoke grep or rg as a Bash command」——强制走专用工具，不许用 bash 抄近路。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Glob&lt;/strong&gt; 结果按修改时间倒序排列（最近改过的排前面），100 文件硬上限。设计哲学跟 IDE 的「最近打开文件」一样。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Read&lt;/strong&gt; 默认只读 2000 行，支持 &lt;code&gt;offset&lt;/code&gt; + &lt;code&gt;limit&lt;/code&gt; 分段读取。关键：&lt;strong&gt;不缓存、不索引&lt;/strong&gt;——每次直接 stat 磁盘文件读最新内容。这就是实时性的来源：没有索引层，就没有索引滞后。&lt;/p&gt;
&lt;h3 id="73-三件套的组合用法"&gt;7.3 三件套的组合用法
&lt;/h3&gt;&lt;p&gt;一个真实场景：「这个项目登录功能在哪实现？」&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;步骤1: Glob **/*login*.{ts,tsx,js}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 返回 5 个候选文件
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;步骤2: Grep passport|auth|login (在这5个文件里搜)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 定位到具体命中行
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;步骤3: Read 命中文件的相关行段
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 看具体实现
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;每一步基于上一步的结果决定下一步——这是和 RAG 范式最大的不同。RAG 是一次性召回所有材料，模型将错就错；Claude Code 是多轮迭代，搜错了下一轮自己调整。&lt;/p&gt;
&lt;h3 id="74-派子-agent-探索解决上下文污染"&gt;7.4 派子 Agent 探索：解决上下文污染
&lt;/h3&gt;&lt;p&gt;简单任务三件套够用。但如果任务是「调研整个项目的认证模块流程」呢？&lt;/p&gt;
&lt;p&gt;这种任务需要 grep 几十个关键词、读十几个文件、来回比对。如果让主 Agent 自己干，它的上下文很快被一堆 grep 输出和文件片段塞满——&lt;strong&gt;上下文污染&lt;/strong&gt;。等它想清楚认证流程、要回头写代码时，真正要解决的问题已经被中间结果挤到角落了。&lt;/p&gt;
&lt;p&gt;Claude Code 的解决办法：&lt;strong&gt;派一个 Explore 子 Agent 去探索&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;主 Agent（上下文保持干净）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 派 Explore 子 Agent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;子 Agent（独立上下文）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ grep 几十次、read 几十次
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 中间结果全留自己上下文里
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;返回精简结论给主 Agent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;主 Agent 上下文只多了一段结论
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;就像老板做战略决策，不会自己扎进 Excel 翻几小时，而是派秘书去调研，秘书看完资料只把结论给老板。&lt;/p&gt;
&lt;p&gt;临界点是「预期超过 3 次查询」——少于 3 次别折腾派 Agent，多于 3 次就别污染主 Agent。&lt;/p&gt;
&lt;h3 id="75-llm-driven-多轮迭代grep-为什么够用"&gt;7.5 LLM-driven 多轮迭代：grep 为什么够用
&lt;/h3&gt;&lt;p&gt;到这里，整个检索系统的层次就清晰了：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;底层：Grep / Glob / Read 三件套 → 简单定向检索
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;中层：Explore 子 Agent → 开放式探索 + 上下文隔离
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;上层：主 Agent 编排 → 整体任务决策
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;但还有一层底层的「灵魂」：&lt;strong&gt;LLM-driven 的多轮迭代循环&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;call_llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tool_use&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;execute_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_use&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;grep 本身不强，但「让 LLM 自己决定每一轮 grep 什么」就强了。你看到 Grep 结果是空的？改个关键字再搜。Read 出来的代码不像你以为的？再 Grep 几个相关函数看看。发现这个文件引用了另一个文件？跟过去看一眼。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RAG 是「考试发卷子」&lt;/strong&gt;——一次性发材料，将错就错。&lt;strong&gt;Claude Code 是「现场探案」&lt;/strong&gt;——边查边推理，走一步看一步。&lt;/p&gt;
&lt;p&gt;两种方案代表两种哲学：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;RAG 派：LLM 不够强，工程帮它把材料准备好&lt;/li&gt;
&lt;li&gt;Claude Code 派：LLM 已经够强，工程给它工具，把决策权还给它&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Anthropic 押注的是「模型会越来越强」，所以他们选择信任模型。&lt;/p&gt;
&lt;h3 id="76-记忆机制不用向量数据库"&gt;7.6 记忆机制：不用向量数据库
&lt;/h3&gt;&lt;p&gt;跟代码检索一样反直觉的，是 Claude Code 的记忆机制——它也不用向量数据库。&lt;/p&gt;
&lt;p&gt;业界主流的记忆方案有四类，但都有共同病根：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方案&lt;/th&gt;
&lt;th&gt;原理&lt;/th&gt;
&lt;th&gt;病根&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;滑动窗口&lt;/td&gt;
&lt;td&gt;保留最近 N 轮&lt;/td&gt;
&lt;td&gt;关键信息和无关信息一起被丢&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;对话摘要&lt;/td&gt;
&lt;td&gt;LLM 定期总结旧对话&lt;/td&gt;
&lt;td&gt;重要细节被压糊&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;向量检索&lt;/td&gt;
&lt;td&gt;embedding + top-K 召回&lt;/td&gt;
&lt;td&gt;相似≠相关、黑盒、维护成本高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;分层存储&lt;/td&gt;
&lt;td&gt;core/recall/archival 三层&lt;/td&gt;
&lt;td&gt;概念多、检索还是靠 embedding&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;四个共同病根：自由文本无约束、不区分类型、没有老化机制、重检索轻写入。&lt;/p&gt;
&lt;h3 id="77-claude-code-的两层记忆架构"&gt;7.7 Claude Code 的两层记忆架构
&lt;/h3&gt;&lt;p&gt;Claude Code 用了&lt;strong&gt;两条独立的线&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;静态层：CLAUDE.md 体系（声明式指令）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 你写好放那里，Agent 启动时全量加载
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 解决「怎么协作」「遵守什么规则」
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ = 公司员工手册
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;动态层：自动记忆系统（学习式偏好）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ Agent 互动中自动写成记忆文件
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 下次对话按需检索
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ = 你的工作笔记
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;静态层在第二章已讲，这里展开动态层。&lt;/p&gt;
&lt;h3 id="78-四种记忆类型"&gt;7.8 四种记忆类型
&lt;/h3&gt;&lt;p&gt;动态层只允许四种类型的记忆，其他一律不许写：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MEMORY_TYPES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;user&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 用户画像：你是谁
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;feedback&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 行为偏好：你不喜欢什么
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;project&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 项目动态：项目正在发生什么
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;reference&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 外部指针：去哪查什么
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;feedback&lt;/code&gt; 和 &lt;code&gt;project&lt;/code&gt; 类型有强制结构：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;name: 不要用 mock 数据库
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;description: 集成测试必须连真实数据库
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;type: feedback
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;集成测试必须连真实数据库，不要用 mock。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gs"&gt;**Why:**&lt;/span&gt; 上季度 mock 测试通过了但 prod 迁移挂了
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gs"&gt;**How to apply:**&lt;/span&gt; 所有标了「集成测试」的 case 都适用
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;为什么这么严？因为只记规则不记原因，遇到边界情况就抓瞎。加上 Why（踩过的坑），Agent 在边界情况能自己判断该不该破例。&lt;/p&gt;
&lt;h3 id="79-该存什么-vs-不该存什么"&gt;7.9 该存什么 vs 不该存什么
&lt;/h3&gt;&lt;p&gt;跟「该存什么」同样重要的是「不该存什么」：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;代码模式、架构、文件路径 → grep / CLAUDE.md 就能得到&lt;/li&gt;
&lt;li&gt;Git 历史和最近改动 → &lt;code&gt;git log&lt;/code&gt; / &lt;code&gt;git blame&lt;/code&gt; 是权威&lt;/li&gt;
&lt;li&gt;调试方案和修复方法 → fix 已经在代码里&lt;/li&gt;
&lt;li&gt;CLAUDE.md 里已经写过的内容&lt;/li&gt;
&lt;li&gt;临时任务状态和当前对话上下文&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;原则是：&lt;strong&gt;只记代码推不出来的东西&lt;/strong&gt;。因为代码是活的，记忆是死的。如果记忆说「AuthService 在第 42 行」但代码已重构，这条记忆就变成了「权威的错误」，比没记忆还糟。&lt;/p&gt;
&lt;h3 id="710-索引常驻--内容按需"&gt;7.10 索引常驻 + 内容按需
&lt;/h3&gt;&lt;p&gt;100 条记忆全塞进 system prompt 会爆窗口，完全不塞 Agent 又不知道有什么。Claude Code 的方案是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;MEMORY.md 索引 → 始终加载进 system prompt（只含 name + description）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;独立记忆文件 → 按需加载（真正需要时才读取完整内容）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;就像翻工具书——你不需要把整本书背下来，但至少得知道目录里都有哪几章。&lt;/p&gt;
&lt;p&gt;索引有双保险截断：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MAX_ENTRYPOINT_LINES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="c1"&gt;// 最多 200 行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MAX_ENTRYPOINT_BYTES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt; &lt;span class="c1"&gt;// 最多 25KB
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;两个限制任意一个先触发就截断。防的是「长行索引炸弹」——曾经观察到 200 行不到但加起来 197KB 的情况。&lt;/p&gt;
&lt;h3 id="711-写入extract-memories-代理"&gt;7.11 写入：Extract Memories 代理
&lt;/h3&gt;&lt;p&gt;记忆怎么写进去？不让主对话自己写（会分心、浪费 token），而是每轮对话结束后，后台单独跑一个 &lt;code&gt;extractMemories&lt;/code&gt; 代理。&lt;/p&gt;
&lt;p&gt;这个代理不是从零启动新对话，而是&lt;strong&gt;完美 fork 主对话&lt;/strong&gt;，复用主对话的 prompt cache。意味着它不用重新加载几千 token 的 system prompt，只需要看着对话历史决定「有没有值得记的东西」，多花的钱很少。&lt;/p&gt;
&lt;h3 id="712-检索用-sonnet-当选择器"&gt;7.12 检索：用 Sonnet 当选择器
&lt;/h3&gt;&lt;p&gt;下次对话来了，100 条记忆怎么挑出最相关的 5 条？&lt;/p&gt;
&lt;p&gt;不用向量检索，&lt;strong&gt;让 Sonnet（小模型）来挑&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;第一步：扫描所有记忆文件的前 30 行（只读 frontmatter）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;第二步：把所有记忆的「标题清单」拼成文本发给 Sonnet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;第三步：Sonnet 用 JSON schema 返回 top-5 文件名
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;System Prompt 写得很严苛：「Only include memories that you are certain will be helpful. Be selective and discerning.」——不确定就别选，宁可少选不可错选。&lt;/p&gt;
&lt;p&gt;为什么用 Sonnet 不用更便宜的 Haiku？因为 Sonnet 比 Haiku 准很多，记忆相关性判错的代价远大于多花的那点钱。&lt;/p&gt;
&lt;p&gt;还有两个过滤细节：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;alreadySurfaced&lt;/code&gt;：上一轮已露过脸的记忆这次排除&lt;/li&gt;
&lt;li&gt;&lt;code&gt;recentTools&lt;/code&gt;：最近用过的工具的「用法文档」不选（正在用就不用看文档），但「警告、坑点」记忆要保留&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="713-老化警告"&gt;7.13 老化警告
&lt;/h3&gt;&lt;p&gt;记忆注入时用 &lt;code&gt;&amp;lt;system-reminder&amp;gt;&lt;/code&gt; 标签包裹，并加上时间警告：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;system-reminder&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;This memory was saved 5 days ago. Verify it&amp;#39;s still accurate before acting on it.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[记忆内容]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/system-reminder&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;今天/昨天 → 不警告
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2 天以前 → 主动加警告
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这解决了向量检索最致命的问题——「权威的错误」。过时记忆不是被闭眼信，而是带着「这是历史，不是现状」的心态去用，发现冲突就更新或忽略。&lt;/p&gt;
&lt;h3 id="实践要点-6"&gt;实践要点
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;代码检索不用 RAG 的六个原因&lt;/strong&gt;：冷启动慢、实时性差、不精确、token 浪费、黑盒、决策权不在模型&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;三件套 + 子 Agent 分层检索&lt;/strong&gt;：&amp;lt; 3 次查询直接三件套，&amp;gt; 3 次派 Explore 子 Agent&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;记忆只记代码推不出来的东西&lt;/strong&gt;——代码是活的，记忆是死的&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;索引常驻 + 内容按需&lt;/strong&gt;——任何「总量大但少数需要展开」的场景都适用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;小模型做选择题 &amp;gt; 向量检索&lt;/strong&gt;——只要候选集不大（几百以内），用模型选更准更便宜&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;记忆要有老化机制&lt;/strong&gt;——2 天前的记忆加 stale 警告，逼模型主动验证&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="第八章-多-agent-协作subagent-实现机制"&gt;第八章 多 Agent 协作：SubAgent 实现机制
&lt;/h2&gt;&lt;h3 id="81-为什么一个-agent-不够用"&gt;8.1 为什么一个 Agent 不够用
&lt;/h3&gt;&lt;p&gt;单个 Agent（一个 LLM + 一堆工具 + 一个循环）在简单任务上挺好用。但真实项目里，一个问题马上就冒出来。&lt;/p&gt;
&lt;p&gt;假设你让一个 Agent 做：「调研 React 18 新特性，在项目里实现一个 useTransition 的例子，最后做代码评审。」三个麻烦同时出现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;上下文会爆炸&lt;/strong&gt;：调研阶段要看大量文档，实现阶段要读项目代码，评审阶段又要重新读实现。三个阶段的内容全塞进一个上下文，token 蹭蹭涨&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;职责混乱&lt;/strong&gt;：一个 Agent 既当研究员又当程序员又当评审员，容易跑偏——调研到一半就开始写代码，代码写到一半又去查文档&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没法并发&lt;/strong&gt;：查文档的时候项目代码干等着&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Multi-Agent 的思路就是老板带团队：把任务拆给不同「专家」，研究员去调研、工程师去写代码、评审员去挑错。老板只看大方向、收结果。&lt;/p&gt;
&lt;h3 id="82-三套不同的机制"&gt;8.2 三套不同的机制
&lt;/h3&gt;&lt;p&gt;Claude Code 源码里跟「多 Agent」沾边的代码其实有三套：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 常规 Subagent │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 主 Agent 派子 Agent 出去，子跑完把结果交回来 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 对应「父子型」 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Fork Subagent │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 派一个「字节级相同」的分身，复用父 Agent 的 Prompt Cache │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 省 80-90% 成本 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Coordinator 模式 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 主 Agent 退化成纯协调者，只派 worker、收结果、合成 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 对应「主从型」，最大化并发 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="83-隔离机制两个维度"&gt;8.3 隔离机制：两个维度
&lt;/h3&gt;&lt;p&gt;隔离是多 Agent 设计最关键的一环。如果隔离不好，一个子 Agent 污染了父 Agent 的状态，整个系统就乱套了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;工具隔离——三道准入门：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;第一道门：全局黑名单（所有子 Agent 通用）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; · 禁止派新 subagent 的工具（防递归嵌套）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; · 禁止主动问用户问题的工具（子 Agent 不抢对话权）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; · 禁止切换规划模式的工具（规划权归主 Agent）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; · 禁止停止其他任务的工具（任务管理是主线程专属）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;第二道门：自定义 Agent 加严黑名单
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; · 用户自己写的 Agent 比内置的再严一道
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;第三道门：后台异步 Agent 走白名单
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; · 只准用事先圈定的一小批工具
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; · 白名单哲学：默认不准用，明确列出的才能用
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;源码里的过滤函数就一个 filter：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;filterToolsForAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isBuiltIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isAsync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;permissionMode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tools&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mcp__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ALL_AGENT_DISALLOWED_TOOLS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isBuiltIn&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;CUSTOM_AGENT_DISALLOWED_TOOLS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isAsync&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;ASYNC_AGENT_ALLOWED_TOOLS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;上下文隔离——按字段粒度决策：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不是一刀切地「全共享」或「全新建」，而是每一项状态单独判断：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;状态&lt;/th&gt;
&lt;th&gt;决策&lt;/th&gt;
&lt;th&gt;原因&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;读文件缓存&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;克隆一份&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;子 Agent 读了文件，父会误以为自己也读过，跳过不读&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;写全局状态&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;直接关闭&lt;/strong&gt;（设为空操作）&lt;/td&gt;
&lt;td&gt;两边同时改同一份状态，界面会花&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;注册后台任务&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;保留通路&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;否则子 Agent 起的后台进程变成孤儿没人回收&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent ID + 深度&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;新建，深度+1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可追踪嵌套层级，超阈值报警防失控&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createSubagentContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parentContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;overrides&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ToolUseContext&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;readFileState&lt;/span&gt;: &lt;span class="kt"&gt;cloneFileStateCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parentContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFileState&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// 克隆
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;setAppState&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="c1"&gt;// 关闭写权限
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;setAppStateForTasks&lt;/span&gt;: &lt;span class="kt"&gt;parentContext.setAppStateForTasks&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;parentContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAppState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 保留任务通路
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;agentId&lt;/span&gt;: &lt;span class="kt"&gt;overrides?.agentId&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;createAgentId&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;// 独立 ID
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;queryTracking&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;chainId&lt;/span&gt;: &lt;span class="kt"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;depth&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parentContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryTracking&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 深度+1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;所谓上下文隔离，不是一刀切地全隔离或不隔离，而是按每个状态的语义单独决策&lt;/strong&gt;。这个细腻劲儿正是工业级产品稳定跑的根基。&lt;/p&gt;
&lt;h3 id="84-父子通信两种形态"&gt;8.4 父子通信：两种形态
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;默认形态——单向通知：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;父 Agent 派子 Agent 出去、等结果，长任务（超 2 分钟）转后台后子 Agent 回头发完成通知。父 Agent 不能中途给在跑的子 Agent 插话，消息基本是&lt;strong&gt;子→父 单向&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;完成通知被包装成 XML，&lt;strong&gt;伪装成一条用户消息&lt;/strong&gt;塞进父 Agent 的对话历史：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;task-notification&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;task-id&amp;gt;&lt;/span&gt;agent-a1b&lt;span class="nt"&gt;&amp;lt;/task-id&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;output-file&amp;gt;&lt;/span&gt;/tmp/xxx.txt&lt;span class="nt"&gt;&amp;lt;/output-file&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;status&amp;gt;&lt;/span&gt;completed&lt;span class="nt"&gt;&amp;lt;/status&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;Agent &amp;#34;Investigate auth bug&amp;#34; completed&lt;span class="nt"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;result&amp;gt;&lt;/span&gt;Found null pointer in src/auth/validate.ts:42...&lt;span class="nt"&gt;&amp;lt;/result&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;usage&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;total_tokens&amp;gt;&lt;/span&gt;12345&lt;span class="nt"&gt;&amp;lt;/total_tokens&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;tool_uses&amp;gt;&lt;/span&gt;8&lt;span class="nt"&gt;&amp;lt;/tool_uses&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;duration_ms&amp;gt;&lt;/span&gt;34567&lt;span class="nt"&gt;&amp;lt;/duration_ms&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/usage&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/task-notification&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;为什么用 XML 不用结构化对象？三个原因：LLM 对 XML 天然友好、纯文本可直接塞进对话历史、伪装成用户消息天然复用 agentic loop 处理逻辑。这种「把系统事件伪装成对话」的设计在 LLM 应用里很值得学。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;团队模式（agent-teams）——双向对讲：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;开启团队模式后，父 Agent 多了一个 &lt;code&gt;SendMessage&lt;/code&gt; 工具，可以往子 Agent 的「信箱」（&lt;code&gt;pendingMessages&lt;/code&gt; 数组）里扔字条。子 Agent 在每轮循环边界自己捡字条，作为「用户消息」注入对话历史。&lt;/p&gt;
&lt;p&gt;如果子 Agent 已经完成停下来了，父 Agent 发 SendMessage 会&lt;strong&gt;自动唤醒&lt;/strong&gt;它——从磁盘 transcript 恢复完整对话历史，拼上新消息重新跑。子 Agent 即使完成了也不是「死了」，随时可被叫醒。&lt;/p&gt;
&lt;h3 id="85-fork-subagent省钱又省延迟的隐藏大招"&gt;8.5 Fork Subagent：省钱又省延迟的隐藏大招
&lt;/h3&gt;&lt;p&gt;每派一个常规子 Agent，如果它有独立的 system prompt（上万 token），API 要从头算一遍。两个代价：&lt;strong&gt;钱&lt;/strong&gt;（input token 重新算）和&lt;strong&gt;延迟&lt;/strong&gt;（首 token 等更久）。&lt;/p&gt;
&lt;p&gt;Prompt Cache 可以缓解——如果 API 请求前缀跟之前一样，这段前缀走缓存，只要原价 10%。但缓存命中条件极严：&lt;strong&gt;字节级别完全相同&lt;/strong&gt;。一个空格不对都 miss。&lt;/p&gt;
&lt;p&gt;Fork Subagent 的思路：派一个子 Agent，它的 system prompt 和工具池跟父 Agent &lt;strong&gt;完全一样&lt;/strong&gt;，复用父的缓存。&lt;/p&gt;
&lt;p&gt;要做到字节级一致，五样必须对齐：系统 prompt 内容、用户上下文、系统上下文、工具池顺序和定义、对话历史前缀。&lt;/p&gt;
&lt;p&gt;Fork 的 system prompt 生成函数直接返回空字符串——不是偷懒，而是&lt;strong&gt;不重新生成，直接用父 Agent 已渲染好的那份字节&lt;/strong&gt;。重新调生成函数可能有微小差异（功能开关缓存状态变了），一个字符不同缓存就没了。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;FORK_AGENT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;agentType&lt;/span&gt;: &lt;span class="kt"&gt;FORK_SUBAGENT_TYPE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// 用父的完整工具池
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;maxTurns&lt;/span&gt;: &lt;span class="kt"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;inherit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 继承父的模型
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;permissionMode&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;bubble&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;getSystemPrompt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 返回空串！直接用父的字节
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Fork 把子 Agent 成本降到原来的 10% 左右。这意味着原本成本考虑不敢派的活，现在都能派了，Agent 系统的能力边界扩大了。&lt;strong&gt;成本优化本身就是能力的一部分&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="86-coordinator-模式真正的多-agent-并行"&gt;8.6 Coordinator 模式：真正的多 Agent 并行
&lt;/h3&gt;&lt;p&gt;Coordinator 模式下，主 Agent 退化成纯协调者——只做三件事：&lt;strong&gt;派 worker、收结果、合成答案&lt;/strong&gt;。不再自己读代码写代码。&lt;/p&gt;
&lt;p&gt;System Prompt 强制约束：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;You&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;coordinator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Your&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Help&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;achieve&lt;/span&gt; &lt;span class="n"&gt;their&lt;/span&gt; &lt;span class="n"&gt;goal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Direct&lt;/span&gt; &lt;span class="n"&gt;workers&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;research&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;implement&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Synthesize&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;communicate&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Answer&lt;/span&gt; &lt;span class="n"&gt;questions&lt;/span&gt; &lt;span class="n"&gt;directly&lt;/span&gt; &lt;span class="n"&gt;when&lt;/span&gt; &lt;span class="n"&gt;possible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;don&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;t delegate work&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="n"&gt;without&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Coordinator 有一句核心 Prompt：「&lt;strong&gt;Parallelism is your superpower. Workers are async. Launch independent workers concurrently whenever possible.&lt;/strong&gt;」&lt;/p&gt;
&lt;p&gt;底层支持是：一条 assistant 消息里可以出现多个派 worker 的工具调用，底层并发执行。协调者一口气派三个 worker 分别调研 auth、session、token 三个模块，三个同时干活，谁先完成谁先通知。&lt;/p&gt;
&lt;p&gt;典型任务流水线分四个阶段：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;阶段&lt;/th&gt;
&lt;th&gt;谁来做&lt;/th&gt;
&lt;th&gt;目的&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;调研&lt;/td&gt;
&lt;td&gt;Workers（并行）&lt;/td&gt;
&lt;td&gt;调查代码库、找文件、理解问题&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;合成&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;协调者本人&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;读完发现、理解问题、写实现规格&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;实现&lt;/td&gt;
&lt;td&gt;Workers&lt;/td&gt;
&lt;td&gt;按规格做具体修改&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;验证&lt;/td&gt;
&lt;td&gt;Workers&lt;/td&gt;
&lt;td&gt;测试改动是否真的工作&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;注意中间「合成」阶段是协调者&lt;strong&gt;亲自&lt;/strong&gt;做。Prompt 反复强调：不要偷懒让 worker「based on your findings, implement the fix」，而是自己把 findings 读懂、写成规格再派下去。&lt;strong&gt;协调者必须理解而不能转发&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;还有一个 Continue vs Spawn 决策：新任务跟 worker 现有上下文高度相关就续命老 worker（省重新加载上下文的开销），不相关或之前走偏了就派新 worker。验证类工作永远派新 worker（避免自己验自己）。&lt;/p&gt;
&lt;h3 id="87-五条-multi-agent-设计原则"&gt;8.7 五条 Multi-Agent 设计原则
&lt;/h3&gt;&lt;p&gt;从 Claude Code 源码里可以提炼出五条直接可用的原则：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;上下文隔离要按字段粒度做&lt;/strong&gt;——不是一刀切全共享或全新建，每个状态单独决策&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通信走消息不走函数调用&lt;/strong&gt;——天然异步、天然支持并发、天然兼容 agentic loop&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具权限要分级管控&lt;/strong&gt;——全局黑名单 + 类型黑名单 + 异步白名单&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缓存友好是一种架构能力&lt;/strong&gt;——设计 subagent 时考虑 prompt 前缀能否复用，能省 80-90% 成本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并行优先 + 协调者合成&lt;/strong&gt;——能并行的绝不串行，协调者亲自合成不转发&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="实践要点-7"&gt;实践要点
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;工具隔离三道门是递归防护的基础&lt;/strong&gt;——不给子 Agent 派子 Agent 的权力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上下文隔离按字段决策&lt;/strong&gt;——读缓存克隆、写状态关闭、任务通路保留、深度+1&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;完成通知伪装成用户消息&lt;/strong&gt;——天然复用 agentic loop，不需要额外状态机&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fork Subagent 在缓存友好场景能省 90% 成本&lt;/strong&gt;——但与 Coordinator 模式互斥&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coordinator 模式的协调者必须合成不转发&lt;/strong&gt;——理解全局做决策，不当传话筒&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;验证类工作永远派新 worker&lt;/strong&gt;——不能让刚写完代码的 worker 自己验自己&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="第九章-系统提示词与-ai-编程方法论"&gt;第九章 系统提示词与 AI 编程方法论
&lt;/h2&gt;&lt;h3 id="91-fable-5-系统提示词泄漏"&gt;9.1 Fable 5 系统提示词泄漏
&lt;/h3&gt;&lt;p&gt;2025 年，Claude Code（内部代号 Fable 5）的一份约 1600 行的系统提示词被泄漏。这份 Prompt 给了我们一个罕见的窗口——看清一个工业级 AI Agent 是怎么给自己「立规矩」的。&lt;/p&gt;
&lt;p&gt;这份 Prompt 大致分两半：前半本定义角色和行为准则，后半本定义工具（17-18 个）。这里挑几个最值得学习的设计。&lt;/p&gt;
&lt;h3 id="92-ask_user_inputwhen-not-to-use-比-when-to-use-详细"&gt;9.2 ask_user_input：WHEN NOT TO USE 比 WHEN TO USE 详细
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;ask_user_input&lt;/code&gt; 是「向用户提问」的工具。有趣的是，它的 Prompt 里「什么时候不要用」比「什么时候要用」写得还详细：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;WHEN NOT TO USE:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 不要用提问逃避给出你自己的观点
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 不要问用户能从代码里推断出来的事
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 不要问偏好（除非真的影响结果且无法合理默认）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;为什么防「用提问逃避给观点」？因为模型有一种倾向——遇到不确定的事就问用户，显得很谨慎。但这其实是在偷懒，把本该自己判断的事推给用户。好 Agent 应该先给出自己的判断和理由，只在真正需要用户决策时才问。&lt;/p&gt;
&lt;h3 id="93-create_file参数顺序逼思考"&gt;9.3 create_file：参数顺序逼思考
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;create_file&lt;/code&gt; 工具的参数顺序是：&lt;code&gt;description&lt;/code&gt; → &lt;code&gt;path&lt;/code&gt; → &lt;code&gt;file_text&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;注意 &lt;code&gt;description&lt;/code&gt; 排在 &lt;code&gt;path&lt;/code&gt; 前面。这不是随便排的——它逼模型先想清楚「这个文件是干什么的」（description），再想「放哪里」（path），最后才写内容（file_text）。&lt;/p&gt;
&lt;p&gt;如果顺序反过来（先 path 再 description），模型可能先随便定个路径就开始写，写到一半才发现目的不明确。参数顺序是一种隐式的思维引导。&lt;/p&gt;
&lt;h3 id="94-message_compose给策略不给语气"&gt;9.4 message_compose：给策略不给语气
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;message_compose&lt;/code&gt; 是「帮用户写消息」的工具。Prompt 要求：给用户策略建议（说什么、怎么说），但不替用户决定语气版本。&lt;/p&gt;
&lt;p&gt;为什么不替用户选语气？因为语气是高度个人化的——同样一个「拒绝合作」的消息，有人喜欢委婉、有人喜欢直接。Agent 给策略（「先肯定对方、再说明限制、最后给替代方案」），让用户自己选语气。&lt;/p&gt;
&lt;h3 id="95-web_search能稳的别搜会变的必搜"&gt;9.5 web_search：能稳的别搜，会变的必搜
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;web_search&lt;/code&gt; 工具的指导原则很精炼：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;能稳的别搜&lt;/strong&gt;：稳定知识（编程语法、历史事件）不搜，模型自己就知道&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;会变的必搜&lt;/strong&gt;：会变的信息（最新版本号、当前天气、新闻）必搜&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;训练时见过个大概 ≠ 现在还了解&lt;/strong&gt;：模型可能「知道」某个 API 的大致用法，但具体参数可能已经变了&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="96-先读-skillmd-是-required-first-step"&gt;9.6 先读 SKILL.md 是 required first step
&lt;/h3&gt;&lt;p&gt;Prompt 里明确写着：遇到 Skill 时，先读 SKILL.md 是「required first step」。甚至有一个叫 &lt;code&gt;product-self-knowledge&lt;/code&gt; 的 Skill，专门让 Agent 查自家产品的知识——连自家产品知识也不信记忆，要现查。&lt;/p&gt;
&lt;p&gt;为什么？因为产品知识会更新。你今天记住的 API 文档，明天可能就改了。最稳的办法是每次都查最新的。&lt;/p&gt;
&lt;h3 id="97-不过度格式化"&gt;9.7 不过度格式化
&lt;/h3&gt;&lt;p&gt;Prompt 里有几条关于输出风格的约束：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;拒绝时不用 bullet points&lt;/strong&gt;——直接说「不行，因为&amp;hellip;」，不要列一堆理由显得在推脱&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不感谢用户 reach out&lt;/strong&gt;——「感谢您联系我们！」这种话是客服腔，Agent 不需要&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不过度格式化&lt;/strong&gt;——简单回答就用纯文本，不要动不动就列表格画图&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些约束的本质是防「AI 上瘾式行为」——模型有时会过度使用格式化来显得「专业」，但其实降低了信息密度。&lt;/p&gt;
&lt;h3 id="98-安全红线讲原则藏机制"&gt;9.8 安全红线：讲原则藏机制
&lt;/h3&gt;&lt;p&gt;安全相关的 Prompt 有一个原则：&lt;strong&gt;讲原则藏机制&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;它告诉模型「不要做什么」，但不告诉它「我们怎么检测你做了没」。因为如果模型知道检测逻辑，它可能会钻空子——「只要不触发检测就行」。不告诉它检测逻辑，它就只能从原则层面遵守。&lt;/p&gt;
&lt;p&gt;还有一条很精辟的判断标准：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果发现自己正在 reframing 一个请求使其 appropriate，那就是 refuse 的 signal。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;翻译：如果你发现自己在「重新包装」一个不当请求让它看起来合理，那说明你应该直接拒绝。不要玩文字游戏。&lt;/p&gt;
&lt;h3 id="99-system-prompt-的动态组装"&gt;9.9 System Prompt 的动态组装
&lt;/h3&gt;&lt;p&gt;实际运行中，System Prompt 不是一份静态文本，而是动态组装的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;角色定义
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;安全红线
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;行为准则
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;操作安全
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;工具使用指南
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Git 安全
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;输出风格（25 词限制）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;环境信息
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;───────────────────
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__ ← 分割线
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;───────────────────
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;动态部分（工具列表、权限、MCP server）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;分割线以上是静态的（基本不变），以下是动态的（每次可能变）。这种分割让 &lt;strong&gt;Prompt Cache&lt;/strong&gt; 能命中静态部分——API 只需要重新算动态部分，省 90% 费用。&lt;/p&gt;
&lt;p&gt;Claude Code 还有三级缓存：全局缓存（跨会话）、组织缓存（跨用户同组织）、会话缓存（单会话内）。&lt;/p&gt;
&lt;h3 id="910-anthropic-40-万次会话研究用好-ai-编程的关键不是会写代码"&gt;9.10 Anthropic 40 万次会话研究：用好 AI 编程的关键不是会写代码
&lt;/h3&gt;&lt;p&gt;2026 年 6 月，Anthropic 发布了一份基于 40 万次真实会话的研究：《Agentic coding and persistent returns to expertise》。&lt;/p&gt;
&lt;p&gt;样本量：约 23.5 万用户、40 万次会话，时间跨度半年。这个体量意味着它说的不是某个大佬的个人感受，而是几十万人沉淀出的统计规律。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心发现 1：人决定「做什么」，Agent 决定「怎么做」。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;用户握着约 70% 的规划类决策（功能要解决什么问题、做成什么样），Claude 握着约 80% 的执行类决策（用哪个函数、代码怎么落地）。「怎么写」这部分本是程序员最值钱的硬功夫，现在大头被 Agent 接走了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心发现 2：会写代码的护城河正在贬值。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在产出代码的会话里，软件工程师成功率 34%，其他职业 29%——只差 5 个点。管理岗、销售、法务这些跟编程八竿子打不着的人，照样把活干成了。甚至管理类的成功率是所有职业里最高的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心发现 3：差距在 prompt 质量。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;新手发一条 prompt，平均撬动 Claude 做 5 个动作、600 字产出；专家发一条，撬动 12 个动作、3200 字。动作差 2.4 倍，产出差 5 倍。&lt;/p&gt;
&lt;p&gt;差距来自「懂行」。一个没踩过坑的后端说「帮我写个扣库存接口」，Claude 给你一段 &lt;code&gt;update set stock = stock - 1&lt;/code&gt;，本地跑没问题。一个被高并发毒打过的老手说「Redis 预扣加 Lua 脚本保证原子性、热点 key 前面挂限流、扣成功异步落库做最终一致」，Claude 噼里啪啦把一整套全搭出来。&lt;/p&gt;
&lt;p&gt;两条 prompt 的差别跟会不会写 Java 语法无关，差的是后者懂「高并发下直接 update 会超卖」「热点 key 得防击穿」——这是架构经验，是领域专业度。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心发现 4：翻车时差距更大。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;会话遇到麻烦时，新手 19% 概率放弃，中级和专家只有 5-7%。懂行的人一眼能看出哪儿不对、知道往哪个方向救；不懂的人面对「看着没毛病、一上量就炸」的代码，根本察觉不到。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心发现 5：及格线特别低。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;成功率曲线：新手 15% → 中级 28% → 专家 33%。最大的跳是从新手到中级（+13%），从中级到专家只多了 5 个点。&lt;/p&gt;
&lt;p&gt;你不需要是二十年行业老炮。只要对手上的事有个「够用的把握」，知道正常活该长什么样、哪些是关键、做出来对不对，你就跨过了那道收益最大的坎。&lt;/p&gt;
&lt;h3 id="911-三件该练的功夫"&gt;9.11 三件该练的功夫
&lt;/h3&gt;&lt;p&gt;这份研究最终落在三件可操作的功夫上：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一，把问题说清楚。&lt;/strong&gt; 不是文采问题，是把「要解决什么、有哪些约束」交代明白。「帮我写扣库存接口」和「Redis 预扣加 Lua 原子扣减、再加限流防超卖」是两个世界。后者多出来的每一句，都是你的架构判断，也是 Claude 多替你干的活。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二，把活拆好。&lt;/strong&gt; 大需求别囫囵丢过去。秒杀下单拆成：限流挡请求 → Redis 预扣 → MQ 削峰 → 异步落库。你拆得清楚，它执行起来才不跑偏，哪一环出问题你也立马定位得到。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三，会验收。&lt;/strong&gt; 它吐出来的代码对不对，你得有本事判断。「本地全绿、一并发就超卖」的坑，靠的是你心里有杆秤、知道得上压测才拦得下来。AI 说没问题，你不能它说行你就信。&lt;/p&gt;
&lt;p&gt;三件事没有一件考编码功底，考的全是对这件事本身理解得够不够透。&lt;/p&gt;
&lt;h3 id="912-这半年任务在变"&gt;9.12 这半年任务在变
&lt;/h3&gt;&lt;p&gt;研究还发现一个趋势：修 bug 的会话从 33% 降到 19%，运维从 14% 涨到 21%，写作和数据分析翻倍从 10% 涨到 20%，整体任务价值平均涨了 27%。&lt;/p&gt;
&lt;p&gt;Agent 正在从「帮你打补丁」的小工，变成能扛更值钱活儿的主力。人也顺势从埋头抠 bug，挪到了更靠近「想清楚要什么」的位置上。&lt;/p&gt;
&lt;p&gt;越往后，「懂行」越值钱。&lt;/p&gt;
&lt;h3 id="实践要点-8"&gt;实践要点
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;System Prompt 的「WHEN NOT TO USE」比「WHEN TO USE」重要&lt;/strong&gt;——防的是模型的偷懒倾向&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;参数顺序是隐式思维引导&lt;/strong&gt;——先想目的再想路径最后写内容&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;讲原则藏机制&lt;/strong&gt;——不要告诉模型检测逻辑，否则它会钻空子&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prompt Cache 的静态/动态分割能省 90% 费用&lt;/strong&gt;——系统提示词要分清不变和会变的部分&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用好 AI 编程靠的是领域专业度不是编码能力&lt;/strong&gt;——把问题说清楚、把活拆好、会验收&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;及格线很低&lt;/strong&gt;——对手上的事有「够用的把握」就能拿走大部分收益&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;这个时代真正稀缺的护城河&lt;/strong&gt;：不是你会背多少语法、记多少 API（Agent 比你熟），而是你在某个领域里比 AI 更懂这件事本身&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;从基础使用到源码架构，从上下文压缩到记忆机制，从代码检索到多 Agent 协作，Claude Code 展示了一个工业级 AI Agent 应有的样子。它的设计哲学可以浓缩为一句话：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不堆复杂度，把已经成熟的简单组件（文件系统 + LLM + 工具循环）组合出比花哨方案更好用的东西。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不用向量数据库，用 grep + 小模型选择；不用复杂的 ReAct，用极简的 Tool-Use Loop；不用滑动窗口，用五层压缩金字塔；不用同步函数调用，用消息队列 + XML 通知。&lt;/p&gt;
&lt;p&gt;每一块拆开看都不复杂，但组合在一起，就成了一个能支撑 Anthropic 级别产品的工业级系统。&lt;/p&gt;
&lt;p&gt;而对于我们每一个使用 AI 编程的人来说，最重要的启示来自那份 40 万次会话的研究：&lt;strong&gt;用好 AI 编程的关键不是会写代码，是懂行&lt;/strong&gt;。把问题说清楚、把活拆好、会验收——这三件事，没有一件考编码功底，考的全是你对这件事本身理解得够不够透。&lt;/p&gt;
&lt;p&gt;这个时代真正稀缺的护城河，不是你会背多少语法、记多少 API。那些 Agent 比你熟得多。&lt;/p&gt;
&lt;p&gt;稀缺的是，你在某个领域里，比 AI 更懂这件事本身。&lt;/p&gt;</description></item><item><title>Agent智能体——从概念到自主推理与行动</title><link>https://blog.irudder.me/ai/ai-systematization/05-Agent-Intelligent-Agent.html</link><pubDate>Tue, 28 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/ai-systematization/05-Agent-Intelligent-Agent.html</guid><description>&lt;h1 id="agent智能体从概念到自主推理与行动"&gt;Agent智能体——从概念到自主推理与行动
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;本文是「AI 知识体系深度教程」系列的第五篇。如果你已经读过前面关于大语言模型、RAG、工具调用与框架的章节，那么本文正是这些知识的&amp;quot;集大成&amp;quot;——Agent 把它们融为一个能自主闭环的完整系统。如果你是直接跳到这一篇的初学者，也不必担心，我们会从最本质的概念讲起，逐步带你走到多 Agent 协作和高级设计。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="核心问题列表"&gt;核心问题列表
&lt;/h2&gt;&lt;p&gt;在进入正文之前，请带着下面这些问题阅读本文。它们贯穿全文，也是工程实践中最常被问到的&amp;quot;灵魂拷问&amp;quot;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Agent 和一个&amp;quot;带插件的大模型&amp;quot;到底有什么本质区别？为什么不能把&amp;quot;会调工具&amp;quot;等同于&amp;quot;是 Agent&amp;quot;？&lt;/li&gt;
&lt;li&gt;普通大模型有哪三大不可逾越的局限？Agent 又是用哪三大能力去突破它们的？&lt;/li&gt;
&lt;li&gt;Workflow、Agent、Tools 这三个常被混用的词，到底谁在做&amp;quot;下一步该干什么&amp;quot;的决策？为什么 Anthropic 说&amp;quot;能用 Workflow 解决的问题，就不要用 Agent&amp;quot;？&lt;/li&gt;
&lt;li&gt;ReAct、Plan-and-Execute、Reflection 三种设计范式各自解决什么层次的问题？什么时候该单独用、什么时候该组合用？&lt;/li&gt;
&lt;li&gt;一个 5 步的任务，ReAct 和 Plan-and-Execute 的 token 消耗为什么能差一倍以上？背后的输入增长机制是什么？&lt;/li&gt;
&lt;li&gt;短期记忆、长期记忆、实体记忆到底有什么不同？为什么&amp;quot;记忆粒度不是越细越好&amp;quot;？&lt;/li&gt;
&lt;li&gt;CoT → ToT → GoT 的演进逻辑是什么？为什么 GoT 在生产环境几乎见不到？&lt;/li&gt;
&lt;li&gt;反思机制为什么必须设&amp;quot;最大 2-3 轮&amp;quot;的硬性上限？为什么多 Agent 互评往往比自我反思更有效？&lt;/li&gt;
&lt;li&gt;什么情况下该&amp;quot;手搓 Agent&amp;quot;而不是用框架？&amp;ldquo;核心手写、周边借用&amp;quot;的折中方案为什么最务实？&lt;/li&gt;
&lt;li&gt;Single-Agent 力不从心的三类任务是什么？为什么生产环境几乎都选 Orchestrator 中心化模式，而不用去中心化？&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="引言agent-是-ai-工程的终极形态"&gt;引言：Agent 是 AI 工程的终极形态
&lt;/h2&gt;&lt;p&gt;过去两年，我们见证了 AI 从&amp;quot;能聊天&amp;quot;到&amp;quot;能做事&amp;quot;的跃迁。这个跃迁的标志，就是 &lt;strong&gt;Agent（智能体）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果你把大语言模型（LLM）比作一个&amp;quot;读过万卷书但只会动嘴的书生&amp;rdquo;——它能告诉你怎么做，却从不会真的去做；那么 Agent 就是给这个书生装上了&amp;quot;手脚&amp;quot;（工具调用）、&amp;ldquo;档案室&amp;rdquo;（记忆）和&amp;quot;项目经理&amp;quot;（规划模块），让它真正成为一个能自主完成目标的&amp;quot;行动派&amp;quot;。&lt;/p&gt;
&lt;p&gt;一句话概括 Agent 的本质：&lt;strong&gt;自主闭环&lt;/strong&gt;——感知目标 → 规划步骤 → 调用工具行动 → 观察结果 → 再感知再规划，如此循环直到任务完成。&lt;/p&gt;
&lt;p&gt;这个&amp;quot;闭环&amp;quot;二字，是理解 Agent 全部设计的钥匙。本文会从概念本质出发，一路讲到核心架构、设计范式、记忆机制、规划与反思，最后落到多 Agent 系统与工程落地。无论你是想建立第一印象的初学者，还是想掌握多 Agent 协作与高级设计的工程师，都能在这篇文章里找到你需要的那一层。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第一章agent-的本质"&gt;第一章：Agent 的本质
&lt;/h2&gt;&lt;h3 id="11-什么是-agent与大模型的本质不同"&gt;1.1 什么是 Agent？与大模型的本质不同
&lt;/h3&gt;&lt;p&gt;很多人第一次接触 Agent 时会问：它和 ChatGPT 这种大模型有什么区别？不就是给大模型加了几个插件吗？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不是。&lt;/strong&gt; 这是最常见的误解。两者的本质区别可以用一个词概括：&lt;strong&gt;自主性&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;大模型&lt;/strong&gt;：本质是一个文本生成器。你给它一段输入，它生成一段输出，交互到此结束。它不会主动决定&amp;quot;我下一步要不要去查个资料&amp;quot;&amp;ldquo;我要不要发封邮件&amp;rdquo;，它只会告诉你&amp;quot;你可以这样查&amp;quot;&amp;ldquo;你可以那样发&amp;rdquo;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent&lt;/strong&gt;：能自主完成目标的 AI 系统。它自己决定&lt;strong&gt;用不用工具、何时用、用哪个&lt;/strong&gt;，自己决定&lt;strong&gt;下一步干什么&lt;/strong&gt;，自己决定&lt;strong&gt;任务算不算完成&lt;/strong&gt;。大模型是被动的应答器，Agent 是主动的行动者。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;用一个生活中的类比：大模型像一个百科全书式的电话客服，你问它答，挂了电话就忘；Agent 像一个能干的私人助理，你给个目标&amp;quot;帮我订下周二去上海的出差&amp;quot;，它会自己去查航班、订酒店、发起报销流程、把结果汇报给你，中途遇到航班取消还会自己改签。&lt;/p&gt;
&lt;h3 id="12-普通大模型的三大局限"&gt;1.2 普通大模型的三大局限
&lt;/h3&gt;&lt;p&gt;要真正理解 Agent，必须先看清它要解决的大模型三大局限。这三大局限是&amp;quot;结构性&amp;quot;的，不是靠 prompt 调优就能绕过的：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;局限一：知识被冻结。&lt;/strong&gt;
大模型的训练数据有截止日期。你问它&amp;quot;今天杭州天气怎么样&amp;quot;&amp;ldquo;苹果公司最新一季营收多少&amp;rdquo;，它要么编一个（幻觉），要么老实承认&amp;quot;我的知识截止到……&amp;quot;。它无法获取任何实时信息，因为它的&amp;quot;知识&amp;quot;在训练完成那一刻就被冻结了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;局限二：不能行动。&lt;/strong&gt;
大模型本质是文本生成器。它能用文字详细描述&amp;quot;如何发一封邮件&amp;quot;&amp;ldquo;如何查一个数据库&amp;quot;&amp;ldquo;如何执行一段 Python 代码&amp;rdquo;，但它自己一个都做不到。它只会告诉你&amp;quot;怎么做&amp;rdquo;，自己从不真的去做。它没有连接真实世界的手脚。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;局限三：没有持续状态。&lt;/strong&gt;
大模型每次调用之间是完全失忆的。你上一轮告诉它&amp;quot;我是做金融的&amp;quot;，下一轮它不记得，除非你把上下文重新传一遍。它没有&amp;quot;记忆&amp;quot;这个概念，无法跨任务、跨会话积累对你的了解。&lt;/p&gt;
&lt;p&gt;这三大局限，构成了 Agent 诞生的&amp;quot;问题驱动&amp;quot;。Agent 的三大核心能力，正是逐一对应去突破它们。&lt;/p&gt;
&lt;h3 id="13-agent-的三大核心能力"&gt;1.3 Agent 的三大核心能力
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;能力一：工具调用（Tool Use）——让 Agent 从&amp;quot;说话&amp;quot;变成&amp;quot;做事&amp;quot;。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是突破&amp;quot;知识冻结&amp;quot;和&amp;quot;不能行动&amp;quot;的关键。给 Agent 接上搜索引擎，它就能获取实时信息；接上邮件 API，它就能真正发邮件；接上代码执行器，它就能真正跑代码。&lt;/p&gt;
&lt;p&gt;这里有一个贯穿全文的核心设计哲学，务必牢记：&lt;strong&gt;决策和执行分离&lt;/strong&gt;。模型只是&amp;quot;大脑&amp;quot;，负责决定&lt;strong&gt;调什么工具、填什么参数&lt;/strong&gt;；真正执行工具的是你的&lt;strong&gt;代码&lt;/strong&gt;，执行结果再反馈给模型。模型从不亲自&amp;quot;动手&amp;quot;，它只下指令。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 决策与执行分离（Agent 核心哲学） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LLM（大脑） 你的代码（手脚） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌─────────┐ ┌──────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 决定调 │ ──JSON─▶│ 解析参数 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 什么工具 │ │ 真正执行工具 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 填什么参 │ │ 返回结果 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─────────┘ ◀───────└──────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 决策者 执行者 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ （只动脑不动手） （真正与外部世界交互） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;能力二：记忆机制——突破&amp;quot;没有持续状态&amp;quot;。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;短期记忆&lt;/strong&gt;：当前任务进行中的中间状态，存在 context window（上下文窗口）里。任务结束就清空，像一个用完即擦的工作台。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;长期记忆&lt;/strong&gt;：跨任务的用户偏好、历史决策、做事方法论，存在向量数据库里，靠语义检索调取。像一个越攒越厚的档案室。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有了记忆，Agent 就不再是&amp;quot;每次都从零开始的失忆者&amp;quot;，而是&amp;quot;能记住你、记住上次怎么解决问题的老手&amp;quot;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;能力三：多步推理与自我纠错——让 Agent 真正&amp;quot;自主&amp;quot;。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是 Agent 区别于&amp;quot;插件大模型&amp;quot;的最关键一点。某个步骤失败了，Agent 不会直接崩掉——它能&lt;strong&gt;感知失败、分析原因、换一种方式重试&lt;/strong&gt;。它能&amp;quot;边做边反思&amp;quot;，根据中途的观察动态调整后续计划。&lt;/p&gt;
&lt;p&gt;正是这第三点，让 Agent 从&amp;quot;会调工具的模型&amp;quot;升级为&amp;quot;能自主闭环的系统&amp;quot;。一个只会按预设顺序调工具的程序不是 Agent；一个能自己决定下一步、并在出错时自己纠偏的，才是。&lt;/p&gt;
&lt;h3 id="14-agent-爆发的三个条件"&gt;1.4 Agent 爆发的三个条件
&lt;/h3&gt;&lt;p&gt;Agent 这个概念其实提出得很早，但为什么直到 2023-2024 年才真正&amp;quot;爆发&amp;quot;？因为三个条件必须&lt;strong&gt;同时&lt;/strong&gt;成熟，缺一不可：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;大模型能力跨过&amp;quot;能用&amp;quot;门槛&lt;/strong&gt;：GPT-4、Claude 3 这一代模型在推理能力和指令遵循能力上发生了质变。再早的模型，给它工具它也用不明白——参数填不对、该调的时候不调、不该调的时候乱调。只有当模型&amp;quot;聪明到能正确决策&amp;quot;时，Agent 才有意义。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;工具调用标准化&lt;/strong&gt;：2023 年 OpenAI 推出 Function Calling，让模型能输出结构化的 JSON 来表达&amp;quot;我要调这个工具、参数是这些&amp;quot;，而不是靠解析自由文本（早期 ReAct 靠正则解析 &lt;code&gt;Action: xxx&lt;/code&gt;，极不稳定）。标准化让&amp;quot;决策和执行分离&amp;quot;真正可靠落地。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;配套生态完善&lt;/strong&gt;：LangChain/LlamaIndex 这类框架大幅降低了开发门槛，向量数据库（Chroma、Pinecone、Milvus 等）解决了长期记忆的存储与检索问题。没有这些&amp;quot;脚手架&amp;quot;，从零搭一个 Agent 的工程成本会劝退绝大多数团队。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;近年来还有两大协议在推动生态标准化：&lt;strong&gt;MCP&lt;/strong&gt;（Model Context Protocol，Anthropic 2024 年底提出，解决&amp;quot;Agent 怎么调工具&amp;quot;，是工具世界的&amp;quot;USB-C 接口&amp;quot;）和 &lt;strong&gt;A2A&lt;/strong&gt;（Agent2Agent，Google 2025 年 4 月提出，解决&amp;quot;Agent 之间怎么协作&amp;quot;）。两者互补：MCP 管 Agent 与工具的连接，A2A 管 Agent 与 Agent 的通信。两者均已捐给 Linux 基金会，走向开放标准。&lt;/p&gt;
&lt;h3 id="15-一个关键词自主闭环"&gt;1.5 一个关键词：自主闭环
&lt;/h3&gt;&lt;p&gt;如果这一章只能记住一个词，那就是&lt;strong&gt;自主闭环&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 感知目标 ──▶ 规划步骤 ──▶ 行动(调工具) ──▶ 观察结果
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 再感知再规划
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (动态调整)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;感知&lt;/strong&gt;：理解用户目标和当前环境（包括工具返回的结果）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;规划&lt;/strong&gt;：把复杂目标拆解成可执行的步骤。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;行动&lt;/strong&gt;：调用工具，与外部世界真实交互。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;再感知&lt;/strong&gt;：把行动结果反馈回来，判断是否需要调整计划。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这四个环节首尾相连、循环往复，就是 Agent 的&amp;quot;心跳&amp;quot;。任何一环缺失，都不是完整的 Agent。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;判断一个系统是不是 Agent，看三点：①能否自主规划多步；②能否通过工具与真实世界交互；③结果能否反馈形成闭环。三者缺一不可。&lt;/li&gt;
&lt;li&gt;永远记住&amp;quot;模型只是大脑，执行靠代码&amp;quot;——这是排查一切 Agent bug 的第一原则。&lt;/li&gt;
&lt;li&gt;别把 Agent 等同于&amp;quot;插件&amp;quot;或&amp;quot;工具调用&amp;quot;。工具调用只是 Agent 能力的一部分，自主性才是它的灵魂。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第二章agent-核心架构"&gt;第二章：Agent 核心架构
&lt;/h2&gt;&lt;h3 id="21-四大核心组件"&gt;2.1 四大核心组件
&lt;/h3&gt;&lt;p&gt;如果把 Agent 比作一家公司，它有四大核心组件，各司其职：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;组件&lt;/th&gt;
&lt;th&gt;公司角色&lt;/th&gt;
&lt;th&gt;职责&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM（大模型）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;老板/大脑&lt;/td&gt;
&lt;td&gt;理解任务、做决策、生成自然语言&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;工具系统&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;外包执行团队&lt;/td&gt;
&lt;td&gt;与外部世界交互（搜索、发邮件、执行代码…）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;记忆系统&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;档案室&lt;/td&gt;
&lt;td&gt;保持状态、跨任务积累经验&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;规划模块&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;项目经理&lt;/td&gt;
&lt;td&gt;把复杂目标拆解成步骤、动态调整计划&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;LLM 核心&lt;/strong&gt;是整个系统的决策中枢。所有输入——用户指令、工具返回、记忆内容——都经过 LLM 理解和决策。其中 &lt;strong&gt;System Prompt&lt;/strong&gt;（系统提示词）相当于 Agent 的&amp;quot;岗位说明书&amp;quot;，定义它的角色、行为边界和输出格式。在实际开发中，调优 System Prompt 占据了相当大的开发时间比例。&lt;/p&gt;
&lt;p&gt;模型选择有一个重要权衡：&lt;strong&gt;大模型做核心决策，小模型做简单任务&lt;/strong&gt;。比如用 GPT-4 / Claude Opus 做规划和关键判断，用 GPT-4o-mini / 开源 7B 模型做意图分类、格式提取这类简单活，是常见的成本优化手段。工具调用的稳定性、上下文窗口大小，也是选型时的硬性考量。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;工具系统&lt;/strong&gt;是 Agent 与外部世界交互的唯一入口。一个关键细节：工具定义只有&amp;quot;名字、描述、参数说明&amp;quot;，&lt;strong&gt;没有执行逻辑&lt;/strong&gt;——执行逻辑在你自己的代码里。工具描述的质量直接影响 Agent 表现：description 写得含糊，模型就会误调或漏调。好工具设计有四原则：职责单一、描述精确、错误信息清晰、参数设计简洁。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;记忆系统&lt;/strong&gt;分几个层次（详见第五章），最基本的两层是：短期记忆（context window，任务结束清空）和长期记忆（向量数据库，跨任务持久）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;规划模块&lt;/strong&gt;负责把复杂目标拆解成步骤，并能在执行中动态调整。提升 LLM 推理能力的技术手段从简单到复杂有 CoT（思维链）、ToT（思维树）、GoT（思维图），工程上更常用的是 Plan-and-Execute（先规划后执行）。&lt;/p&gt;
&lt;h3 id="22-workflow--agent--tools-三层概念区分"&gt;2.2 Workflow / Agent / Tools 三层概念区分
&lt;/h3&gt;&lt;p&gt;这三个词在日常讨论里经常被混用，但它们其实是&lt;strong&gt;粒度从小到大的三层结构，可相互嵌套&lt;/strong&gt;。区分它们最核心的角度只有一个：&lt;strong&gt;谁来做&amp;quot;下一步该干什么&amp;quot;的决策？&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 三层结构：粒度从小到大，可相互嵌套 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Tools（最小能力积木） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├─ 本质：按特定格式暴露给 LLM 的函数 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├─ 不做决策，只执行，甚至不知道自己&amp;#34;应该&amp;#34;何时被用 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─ 像瑞士军刀的刀片，决定拿哪个的是拿着刀的手(Agent) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Agent（拿工具自己做决定的人） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├─ Agent = 拿着工具、自己决定用哪个的角色 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├─ 运行方式：Thought→Action→Observation 循环 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├─ while True 跑几次开发者完全不知道 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─ 执行路径由 LLM 实时决定 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Workflow（总指挥） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├─ 把整个流程&amp;#34;骨架&amp;#34;写在代码里 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├─ LLM/Agent/Tools 都是节点 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─ &amp;#34;下一步去哪&amp;#34;全由开发者代码(if/elif)决定 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tools&lt;/strong&gt;：最小的能力积木。本身&lt;strong&gt;无决策能力&lt;/strong&gt;，甚至不知道自己&amp;quot;应该&amp;quot;何时被用。它只是按特定格式暴露给 LLM 的函数（配 schema：名字、描述、参数类型）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent&lt;/strong&gt;：拿着工具、自己决定用哪个的角色。运行方式是一个循环：想清楚（Thought）→ 行动（Action）→ 看结果（Observation）→ 再想清楚 → 再行动，直到 LLM 判断完成。&lt;code&gt;while True&lt;/code&gt; 循环跑几次，开发者完全不知道——执行路径由 LLM 实时决定。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Workflow&lt;/strong&gt;：把整个执行流程的&amp;quot;骨架&amp;quot;写在代码里，LLM/Agent/Tools 都是节点，&lt;strong&gt;下一步去哪全由开发者代码决定&lt;/strong&gt;。LLM 只是流程里的一个&amp;quot;工位&amp;quot;，接下来去哪由 &lt;code&gt;if/elif&lt;/code&gt; 控制。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;三者对比表：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;Tools&lt;/th&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Workflow&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;决策能力&lt;/td&gt;
&lt;td&gt;无（只执行）&lt;/td&gt;
&lt;td&gt;有（LLM 自主决策）&lt;/td&gt;
&lt;td&gt;无（代码写死）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;执行方式&lt;/td&gt;
&lt;td&gt;被动等待&lt;/td&gt;
&lt;td&gt;主动循环至完成&lt;/td&gt;
&lt;td&gt;按定义顺序执行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;确定性&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;低（同输入可能不同路径）&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;灵活性&lt;/td&gt;
&lt;td&gt;只做一件事&lt;/td&gt;
&lt;td&gt;高（应对预料外情况）&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;调试难度&lt;/td&gt;
&lt;td&gt;容易&lt;/td&gt;
&lt;td&gt;难（路径不确定）&lt;/td&gt;
&lt;td&gt;容易（链路清晰）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;适用场景&lt;/td&gt;
&lt;td&gt;封装单一能力&lt;/td&gt;
&lt;td&gt;路径未知的复杂任务&lt;/td&gt;
&lt;td&gt;流程固定的业务系统&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="23-agent-vs-workflow-的本质区别"&gt;2.3 Agent vs Workflow 的本质区别
&lt;/h3&gt;&lt;p&gt;这是工程中最常被问到的辨析。一句话：&lt;strong&gt;Workflow 是确定性流程图，每步硬编码；Agent 把&amp;quot;下一步做什么&amp;quot;的决策权交给 LLM。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;代码结构上的对比最直观：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Workflow：每行都是明确指令，&amp;#34;下一步去哪&amp;#34;由代码决定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;workflow_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm_classify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# LLM 只做分类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;refund&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handle_refund&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 代码决定走退款分支&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;consult&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handle_consult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 代码决定走咨询分支&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Agent：loop 里只有 llm.decide()，&amp;#34;下一步做什么&amp;#34;由 LLM 决定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;agent_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_steps&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;decision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# LLM 决定下一步&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;decision&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_final&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;decision&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;answer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decision&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Workflow 的优点&lt;/strong&gt;：可预测、可控、好调试。缺点是灵活性低，遇到预料外的情况容易失败。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent 的优点&lt;/strong&gt;：能处理没设计过的情况，灵活。缺点是行为不确定、难复现。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;正因为两者各有优劣，生产环境的主流是 &lt;strong&gt;Agentic Workflow（智能体工作流）&lt;/strong&gt;：用 Workflow 固定主流程骨架，需要灵活判断的节点嵌入 Agent，其余固定节点用 LLM/Tools。Anthropic 有一个著名的工程原则：&lt;strong&gt;能用 Workflow 解决的问题，就不要用 Agent&lt;/strong&gt;——因为可控性比灵活性更重要。先从最简单的 Workflow 开始，发现某个节点确实需要灵活决策，才把它升级为 Agent。&lt;/p&gt;
&lt;p&gt;Anthropic 总结了几种主流 Workflow 编排模式，值得了解：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prompt Chaining（提示链）&lt;/td&gt;
&lt;td&gt;前一步输出作为后一步输入，流水线串联&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Routing（路由）&lt;/td&gt;
&lt;td&gt;LLM 分类 → 分发到不同分支&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parallelization（并行化）&lt;/td&gt;
&lt;td&gt;子任务并行执行，最后汇总&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Orchestrator-Workers&lt;/td&gt;
&lt;td&gt;中央编排者分配，多 Worker 各自完成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evaluator-Optimizer&lt;/td&gt;
&lt;td&gt;生成者产出 → 评估者审查 → 不通过反馈重做&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="24-决策和执行分离的设计哲学"&gt;2.4 决策和执行分离的设计哲学
&lt;/h3&gt;&lt;p&gt;这条原则贯穿 Agent 设计的方方面面，值得单独强调。&lt;/p&gt;
&lt;p&gt;为什么要把&amp;quot;决策&amp;quot;和&amp;quot;执行&amp;quot;分开？因为&lt;strong&gt;模型的强项是理解和判断，代码的强项是可靠执行&lt;/strong&gt;。让模型去&amp;quot;想&amp;quot;该做什么，让代码去&amp;quot;做&amp;quot;具体的事，两者各司其职：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模型决定&lt;strong&gt;调什么工具、填什么参数&lt;/strong&gt;（决策）&lt;/li&gt;
&lt;li&gt;代码负责&lt;strong&gt;真正调用 API、执行函数、返回结果&lt;/strong&gt;（执行）&lt;/li&gt;
&lt;li&gt;结果再回到模型，由模型决定&lt;strong&gt;下一步怎么办&lt;/strong&gt;（再决策）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种分离带来了巨大的工程好处：工具的实现可以独立优化、独立测试，不依赖模型的稳定性；模型可以换（GPT-4 换 Claude），只要决策逻辑不变，工具代码一行都不用改。这也是为什么 MCP 协议能成立——它标准化的正是&amp;quot;决策（模型）&amp;ldquo;和&amp;quot;执行（工具 Server）&amp;ldquo;之间的接口。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;看到任何 Agent 实现，第一件事就是问自己：&amp;ldquo;这个系统里，谁在做&amp;rsquo;下一步该干什么&amp;rsquo;的决策？&amp;quot;——这决定了它是 Workflow、Agent 还是 Agentic Workflow。&lt;/li&gt;
&lt;li&gt;生产环境优先用 Agentic Workflow（骨架固定 + 关键节点嵌 Agent），不要一上来就上纯 Agent。&lt;/li&gt;
&lt;li&gt;工具描述写得越精确，Agent 越不容易误调。把工具当产品来设计，description 当产品说明书来写。&lt;/li&gt;
&lt;li&gt;Agent 必须有停止条件：LLM 主动判断完成、最大循环次数（如 15 轮）、总 token 预算上限、超时机制（如 60 秒），通常多个机制同时存在，哪个先触发用哪个。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第三章agent-设计范式"&gt;第三章：Agent 设计范式
&lt;/h2&gt;&lt;h3 id="31-为什么需要不同的设计范式"&gt;3.1 为什么需要不同的设计范式
&lt;/h3&gt;&lt;p&gt;设计范式，就是搭 Agent 的&amp;quot;顶层做事流程框架&amp;rdquo;，类比公司的管理制度。不同的任务有不同的特征——有的简单、有的复杂、有的路径明确、有的需要高质量输出——用一套流程硬套所有任务，要么浪费成本，要么做不好。&lt;/p&gt;
&lt;p&gt;Agent 有三种主流设计范式：&lt;strong&gt;ReAct&lt;/strong&gt;（推理与行动交替）、&lt;strong&gt;Plan-and-Execute&lt;/strong&gt;（先规划后执行）、&lt;strong&gt;Reflection&lt;/strong&gt;（反思驱动改进）。需要特别注意的是，&lt;strong&gt;三者不是互斥的平行选项&lt;/strong&gt;：Reflection 不是独立流程，而是叠加在前两者之上的&amp;quot;质量 buff&amp;rdquo;；实际工程中三者常常混合使用。&lt;/p&gt;
&lt;p&gt;先看一个总览，理解三者各解决什么层次的问题：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;范式&lt;/th&gt;
&lt;th&gt;解决的问题&lt;/th&gt;
&lt;th&gt;定位&lt;/th&gt;
&lt;th&gt;类比&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ReAct&lt;/td&gt;
&lt;td&gt;单步灵活性&lt;/td&gt;
&lt;td&gt;边想边干，走一步看一步&lt;/td&gt;
&lt;td&gt;外卖骑手实时导航&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plan-and-Execute&lt;/td&gt;
&lt;td&gt;长任务跑偏&lt;/td&gt;
&lt;td&gt;先想全再干，全局视野&lt;/td&gt;
&lt;td&gt;项目经理先排计划&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reflection&lt;/td&gt;
&lt;td&gt;输出质量不够&lt;/td&gt;
&lt;td&gt;给前两者加&amp;quot;检查 buff&amp;rdquo;&lt;/td&gt;
&lt;td&gt;考试做完回头检查&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="32-reactreasoning--acting推理与行动交替"&gt;3.2 ReAct（Reasoning + Acting）：推理与行动交替
&lt;/h3&gt;&lt;h4 id="完整的-thought--action--observation-循环"&gt;完整的 Thought → Action → Observation 循环
&lt;/h4&gt;&lt;p&gt;ReAct（2022 年由 Yao 等人提出）的核心思想是：在 CoT（思维链）的推理过程里，插入真实的&amp;quot;行动&amp;quot;。每一轮循环是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Thought（思考）→ Action（行动）→ Observation（观察）→ 再 Thought ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Thought&lt;/strong&gt;：先分析当前情况，决定下一步该做什么。这一步防止&amp;quot;冲动决策&amp;quot;——不先想就乱调工具。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Action&lt;/strong&gt;：根据思考结果，调用一个工具（或给出最终答案）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Observation&lt;/strong&gt;：工具返回的结果，作为下一轮思考的事实依据。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;循环往复，直到 LLM 判断任务完成，输出 &lt;code&gt;Final Answer&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;为什么不能只用 CoT（纯推理）或只用 Act-only（纯行动）？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;纯 CoT&lt;/strong&gt;：只在脑子里推，拿不到真实数据，容易产生幻觉（它&amp;quot;想&amp;quot;出来的&amp;quot;事实&amp;quot;可能是编的）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;纯 Act-only&lt;/strong&gt;：不写思考过程，动作序列脆弱——一步错全跑偏。研究显示在 HotpotQA 等任务上准确率明显更低。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ReAct&lt;/strong&gt;：把推理和行动交织——Thought 定方向，Action 落地，Observation 带回事实，三者闭环互补。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="react-的实现细节"&gt;ReAct 的实现细节
&lt;/h4&gt;&lt;p&gt;理解 ReAct 实现最关键的一点：&lt;strong&gt;循环不是 LLM 自己转的，是代码驱动的&lt;/strong&gt;。LLM 每次只做一件事——根据历史输出下一步的 Thought + Action。代码负责：检测输出、判断有没有 Final Answer、解析 Action、执行工具、把 Observation 填回历史、再次调用 LLM。&lt;/p&gt;
&lt;p&gt;ReAct 的经典 prompt 格式：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Thought: 你的思考过程
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Action: 工具名称
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Action Input: 工具输入参数
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Observation: （系统填入工具结果）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;... 可重复多轮 ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Final Answer: 最终答案
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;完整的 ReAct 实现代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;react_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_steps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; ReAct Agent 的核心实现。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 关键理解：循环由代码驱动，LLM 每次只输出一步 Thought+Action。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_react_prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;# 短期记忆：记录每一步的思考和观察&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_steps&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 1. 调用 LLM，让它基于历史输出下一步&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 2. 检查是否给出最终答案&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Final Answer:&amp;#34;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Final Answer:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 3. 解析出 Action 和参数（决策）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 4. 代码执行工具（执行），把结果作为 Observation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;action_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;工具 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 不存在，请从可用工具中选择&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 5. 把 LLM 输出和观察结果都存入历史，供下一轮参考&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Observation: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;observation&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;超过最大步数，任务未完成&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;现代演进：GPT-4 / Claude 3 之后，模型原生支持 Function Calling / Tool Use，直接输出结构化 JSON，不再靠解析文本。但&lt;strong&gt;本质循环不变&lt;/strong&gt;——只是&amp;quot;行动&amp;quot;从解析文本变成了解析 JSON。&lt;/p&gt;
&lt;p&gt;ReAct 有两个著名的坑：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;循环漂移&lt;/strong&gt;：因为没有全局计划约束，跑着跑着容易偏离目标。比如让 Agent 查苹果营收，它查着查着被&amp;quot;三星竞争&amp;quot;的信息吸引，跑去搜三星了。步骤越多、历史越长，漂移概率越大。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误传播&lt;/strong&gt;：每步决策建立在前面结果上，中间一步错，全链带跑偏；而且 ReAct 没有内置&amp;quot;回头检查&amp;quot;机制，默认 Observation 都是对的。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;根源在于：ReAct 是&lt;strong&gt;纯前向推理&lt;/strong&gt;，无全局规划、无反思。这正是 Plan-and-Execute 和 Reflection 要解决的问题。&lt;/p&gt;
&lt;h3 id="33-plan-and-execute先规划后执行"&gt;3.3 Plan-and-Execute：先规划后执行
&lt;/h3&gt;&lt;h4 id="与-react-的核心区别"&gt;与 ReAct 的核心区别
&lt;/h4&gt;&lt;p&gt;ReAct 是&amp;quot;边走边问路&amp;quot;，Plan-and-Execute 是&amp;quot;先看地图再出发&amp;quot;。&lt;/p&gt;
&lt;p&gt;核心区别一句话：&lt;strong&gt;规划推理和执行推理完全解耦&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReAct：每一步都是即时决策，没有提前的全局规划。&lt;/li&gt;
&lt;li&gt;Plan-and-Execute：先由 Planner 站在全局视角输出完整步骤列表，再由 Executor 逐步执行，每步执行时始终知道自己在整体计划中的位置。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它还有一个&lt;strong&gt;隐藏优势&lt;/strong&gt;：因为规划和执行分离，可以用不同的模型——&lt;strong&gt;规划用强模型&lt;/strong&gt;（GPT-4 / Claude Opus，保证方向正确），&lt;strong&gt;执行用便宜小模型&lt;/strong&gt;（GPT-4o-mini / 开源 7B，只做具体执行）。这种&amp;quot;大小模型搭配&amp;quot;可以降低 70%-90% 的成本，是生产环境非常重要的优化手段。&lt;/p&gt;
&lt;h4 id="适用场景"&gt;适用场景
&lt;/h4&gt;&lt;p&gt;Plan-and-Execute 的优势在&amp;quot;长任务、多步骤、需要全局统筹&amp;quot;的场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;写一份竞品分析报告（要先调研多个竞品、再对比、再撰写）&lt;/li&gt;
&lt;li&gt;全流程的项目开发（需求分析 → 架构设计 → 编码 → 测试）&lt;/li&gt;
&lt;li&gt;多维度行业调研（并行搜集多个维度的信息再汇总）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;代价是：多了一次规划 LLM 调用，延迟成本增加；如果初始规划方向就错了，后续执行再好也难挽回。所以它有一个关键机制——&lt;strong&gt;动态重规划（Dynamic Replan）&lt;/strong&gt;：每步执行完，把结果和剩余计划交给规划器，判断计划是否还适用、需不需要调整。类比导航遇到封路自动重新规划路线。&lt;/p&gt;
&lt;p&gt;完整的 Plan-and-Execute 实现代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plan_and_execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;planner_llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;executor_llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_replans&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Plan-and-Execute 实现。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 规划与执行解耦，支持动态重规划，支持大小模型搭配。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 阶段一：Planner 生成全局计划（用强模型）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;plan_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;请为以下任务制定一个清晰的分步执行计划。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 任务：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 输出格式：编号列表，每步一个独立的原子操作。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse_plan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;planner_llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plan_prompt&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 阶段二：Executor 逐步执行（用便宜小模型，可用 ReAct）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;execution_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;execute_step_with_react&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;executor_llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;execution_context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 阶段三：Re-planner 检查是否需要调整计划（触发条件：执行失败/输出差异大）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;should_replan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;replan_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;原计划：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;已执行到第&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;步&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;最新结果：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;adjust_plan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;planner_llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;replan_context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;max_replans&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;max_replans&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 阶段四：汇总各步产出，生成连贯最终结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;final&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor_llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;任务：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;各步结果：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;请整合为最终输出。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;final&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="34-reflection反思驱动改进"&gt;3.4 Reflection：反思驱动改进
&lt;/h3&gt;&lt;h4 id="反思机制闭环"&gt;反思机制闭环
&lt;/h4&gt;&lt;p&gt;Reflection（反思）的核心定位必须先讲清楚：&lt;strong&gt;它不是独立的完整流程，而是叠加在 ReAct / Plan-and-Execute 之上的增强机制&lt;/strong&gt;。前两者的核心是&amp;quot;把事做完&amp;quot;，Reflection 的核心是&amp;quot;把事做好&amp;quot;。&lt;/p&gt;
&lt;p&gt;它的循环是：&lt;strong&gt;生成 → 评估 → 改进&lt;/strong&gt;，类比&amp;quot;草稿 → 批阅 → 修改&amp;quot;，改完再审阅，直到通过。&lt;/p&gt;
&lt;p&gt;一个关键变体是 &lt;strong&gt;Reflexion&lt;/strong&gt;（Shinn 2023）：不只说&amp;quot;不好重做&amp;quot;，而是生成&amp;quot;反思总结&amp;quot;——记录失败原因和改进建议，存进记忆，作为下次尝试（甚至下次类似任务）的上下文。类比&amp;quot;写错题本&amp;quot;。效果数据很亮眼：HumanEval 上 GPT-4 直接做 pass@1 是 80%，加上 Reflexion 提升到 91%，超过 10 个百分点。它被称为&amp;quot;verbal reinforcement learning&amp;quot;（语言强化学习）——不需要梯度更新，就能从错误中学习。代码生成天然适合 Reflexion，因为可以运行测试，执行结果是直接反馈。&lt;/p&gt;
&lt;h4 id="与前两者的组合使用"&gt;与前两者的组合使用
&lt;/h4&gt;&lt;p&gt;Reflection 最常见的用法是&lt;strong&gt;叠加&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Plan-and-Execute 全局规划 + ReAct 单步执行 + Reflection 关键步骤把关&lt;/li&gt;
&lt;li&gt;写生产代码：Executor 写完 → Critic 审查 → 不通过则改进 → 再审查&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;完整的 Reflection 实现代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reflection_loop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;generator_llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;critic_llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_rounds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; Reflection 反思机制实现。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 核心循环：生成 → 评估 → 改进，直到 PASS 或达到最大轮次。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 初始生成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;current_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;generator_llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;任务：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;请完成。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;round&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_rounds&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 评估：让 Critic 检查当前输出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;eval_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;任务：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 当前输出：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;current_output&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 请评估以上输出：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 1. 有没有事实错误或逻辑问题？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 2. 有没有遗漏重要内容？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 3. 表达是否清晰准确？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 如果输出已经足够好，回复「PASS」；
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 否则指出具体问题并给出改进建议。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;reflection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;critic_llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eval_prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PASS&amp;#34;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;reflection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;current_output&lt;/span&gt; &lt;span class="c1"&gt;# 通过，返回&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 改进：三样东西缺一不可——原始任务 + 当前输出 + 评估意见&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;improve_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;原始任务：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 当前输出：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;current_output&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 评估意见：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reflection&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 请根据评估意见改进输出：&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;current_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;generator_llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;improve_prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;current_output&lt;/span&gt; &lt;span class="c1"&gt;# 达到最大轮次，强制退出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里有两个&lt;strong&gt;关键设计&lt;/strong&gt;，是反思机制能不能真正起作用的命门：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;必须给出明确的检查维度&lt;/strong&gt;（事实/逻辑/完整性/表达），而不是让 LLM 自由发挥。无方向的评估会流于表面——LLM 可能只说&amp;quot;看起来不错&amp;quot;敷衍了事。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;必须有&amp;quot;PASS&amp;quot;机制&lt;/strong&gt;——给 LLM 一个&amp;quot;够好了就停&amp;quot;的出口。没有这个出口，LLM 会陷入&amp;quot;为了改而改&amp;quot;的无限循环，每轮改动很小但无实质进步，甚至把原本对的改错。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;改进 prompt 里&lt;strong&gt;三样东西缺一不可&lt;/strong&gt;：原始任务、当前输出、评估意见。缺原始输出 → 不知在什么基础上改；缺评估意见 → 不知改哪里；缺任务 → 改着改着偏离原始目标。三者都在，才能做到&amp;quot;有针对性的修改&amp;quot;，而非&amp;quot;全部重写&amp;quot;。&lt;/p&gt;
&lt;h3 id="35-三种范式的核心区别与选型"&gt;3.5 三种范式的核心区别与选型
&lt;/h3&gt;&lt;h4 id="token-消耗量化分析"&gt;token 消耗量化分析
&lt;/h4&gt;&lt;p&gt;这是一个常被忽视但极其重要的工程维度。以一个 &lt;strong&gt;5 步任务、每步约 2000 token&lt;/strong&gt; 为例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ReAct 的输入增长（每次带完整历史）：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第1步: 2000 token
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第2步: 2000 + 2000 = 4000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第3步: 2000 + 4000 = 6000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第4步: 2000 + 6000 = 8000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第5步: 2000 + 8000 = 10000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 合计输入 ≈ 30000 token
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Plan-and-Execute：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 规划一次: ~3000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 执行每步(只带自己那步context): ~1500 × 5 = 7500
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 汇总一次: ~4000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 合计 ≈ 14500 token（比 ReAct 低一半多）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;叠加 Reflection：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 每个反思节点至少多一次调用，在基础上再增 30%-100%
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;ReAct 的 token 随步数&lt;strong&gt;线性甚至超线性增长&lt;/strong&gt;（因为每次都带完整历史），而 Plan-and-Execute 把历史&amp;quot;分散&amp;quot;到各步，总消耗低很多。步数越多，这个差距越大。这也是长任务该优先考虑 Plan-and-Execute 的重要原因。&lt;/p&gt;
&lt;h4 id="实际项目选型建议"&gt;实际项目选型建议
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 选型决策树 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 任务简单、流程不固定？ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 是 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ReAct（够用就好，实现简单、灵活、逻辑透明） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 任务长、易跑偏、需整体结构？ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 是 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Plan-and-Execute（遇意外加动态 Replan） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 输出要求高、不能出错？ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 是 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 在前两者基础上叠加 Reflection │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 需跨任务积累经验、避免重复犯错？ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 是 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Reflexion（把失败经验存进记忆，下次参考） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 最常见的混合方案： │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Plan-and-Execute(全局规划) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ + ReAct(单步执行) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ + Reflection(关键步骤把关) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;一句话口诀：&lt;strong&gt;先 ReAct 玩明白，按需往上加。&lt;/strong&gt; 最大的坑是&amp;quot;全堆一起过度工程化&amp;quot;——一上来就 Plan-and-Execute + ReAct + Reflection + Reflexion 全上，复杂度爆炸，调试地狱。先从最简单的 ReAct 跑通，发现长任务跑偏再加 Plan-and-Execute，发现输出质量不够再加 Reflection，循序渐进。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reflection 不是独立流程，是&amp;quot;叠加 buff&amp;quot;——这一点必须在选型时先说清，否则会把三者当成平行选项来纠结。&lt;/li&gt;
&lt;li&gt;反思最多 2-3 轮，绝对不能依赖 LLM 自己判断停止。硬性轮次上限是唯一可靠的退出机制。&lt;/li&gt;
&lt;li&gt;规划用强模型、执行用便宜小模型的&amp;quot;大小模型搭配&amp;quot;，是 Plan-and-Execute 最重要的成本优化手段。&lt;/li&gt;
&lt;li&gt;token 消耗不是小问题：ReAct 在长任务上的线性增长会迅速吃掉预算，这也是长任务该用 Plan-and-Execute 的硬理由。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第四章任务拆分"&gt;第四章：任务拆分
&lt;/h2&gt;&lt;h3 id="41-为什么要拆分复杂任务"&gt;4.1 为什么要拆分复杂任务
&lt;/h3&gt;&lt;p&gt;让 LLM 一次性处理太复杂的任务，几乎必然出错：搜索掺杂分析、写到一半忘了前面的数据、结构混乱、前后矛盾。&lt;/p&gt;
&lt;p&gt;根本原因在于：&lt;strong&gt;context window 有上限，任务越大、中间状态越多，&amp;ldquo;桌面&amp;quot;越乱，越难持续追踪子目标&lt;/strong&gt;。就像你在一张小桌子上同时做五件事，资料堆得满桌都是，做着做着就找不着北了。&lt;/p&gt;
&lt;p&gt;拆分后，每一步只聚焦一件事，桌面干净、质量高；而且每步独立，可以单独验证、单独重试——某步错了不用整个任务重来。&lt;/p&gt;
&lt;h3 id="42-任务拆分的策略"&gt;4.2 任务拆分的策略
&lt;/h3&gt;&lt;p&gt;有两种拆分思路：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态拆分&lt;/strong&gt;：提前写死步骤（这是 Workflow 的思路）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;例：搜索资料 → 整理大纲 → 逐段撰写 → 润色校对。&lt;/li&gt;
&lt;li&gt;优点：可预测、好排查。缺点：灵活性低。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;动态拆分&lt;/strong&gt;：让 LLM 自己规划（这是 Plan-and-Execute 的核心）。&lt;/p&gt;
&lt;p&gt;Plan-and-Execute 的三阶段：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 动态拆分的三阶段（Plan-and-Execute） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 1. 规划（项目启动会） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LLM 输出有序步骤列表，只规划不执行 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 2. 执行（各部门干活） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 逐步执行，每步带前面结果作 context │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 3. 汇总（项目验收） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 整合各步骤产出，解决衔接，生成连贯整体 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;优点：灵活。缺点：规划质量不稳定，规划错了则全错。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意区分一个容易混淆的点&lt;/strong&gt;：CoT/ToT 讲的是&amp;quot;LLM 内部怎么想清楚&amp;rdquo;，是推理层面；静态/动态拆分讲的是&amp;quot;Agent 怎么把大任务切成独立执行步骤&amp;quot;，是工程层面。粒度和目标都不同。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;拆分粒度的把握&lt;/strong&gt;是关键：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;太细&lt;/strong&gt;：步骤多、token 升，太碎看不到全局，衔接生硬。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;太粗&lt;/strong&gt;：每步事多易错，出错难定位。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标准：原子操作&lt;/strong&gt;——只做一件独立的事，边界清晰，做完有明确输出，不互相依赖。&lt;/li&gt;
&lt;li&gt;判断方法：能写清晰的函数签名 → 大概是原子；函数里还要分阶段 → 需要再拆。
&lt;ul&gt;
&lt;li&gt;原子：「搜索竞品 A 的产品信息」&lt;/li&gt;
&lt;li&gt;非原子：「整理竞品分析」（含搜索、筛选、格式化三件事）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;还有一种进阶策略叫&lt;strong&gt;自适应拆分&lt;/strong&gt;：不在开始时定死粒度，执行中根据难度动态调整。逻辑是：先试，做不好（超最大步数/质量不达标）→ 交给规划器再拆 → 对子任务重复。像递归展开的任务树，只有做不好的节点才拆，简单的直接做。特性是：任务越复杂递归层数越深，开销与实际难度成正比，不一刀切。&lt;/p&gt;
&lt;h3 id="43-并行优化"&gt;4.3 并行优化
&lt;/h3&gt;&lt;p&gt;拆分还有一个重要收益：&lt;strong&gt;无依赖的步骤可以并行执行&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;分析步骤之间的依赖关系，无依赖的可以同时跑。类比厨师：烧水的同时切菜腌肉，总时间由最长路径决定。用 &lt;strong&gt;DAG（有向无环图）&lt;/strong&gt; 建模：节点是步骤，边是依赖，无依赖的节点可同时跑。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_parallel_steps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;independent_steps&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;并行执行无依赖的步骤，总时间由最慢的步骤决定&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;execute_step_async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;independent_steps&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;实际项目通过并行优化可以降低 40%-60% 的端到端延迟。但前提是：依赖稀疏、工具 I/O 占主要耗时。如果步骤之间是强依赖（必须串行），并行空间为零。&lt;/p&gt;
&lt;h3 id="44-效果如何提升"&gt;4.4 效果如何提升
&lt;/h3&gt;&lt;p&gt;拆分带来的提升是全方位的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;质量提升&lt;/strong&gt;：每步聚焦一件事，context 干净，LLM 发挥更稳定。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可验证性&lt;/strong&gt;：每步有明确完成标准，像单元测试断言，缺了可以自动重试。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可恢复性&lt;/strong&gt;：某步出错只重试那一步，不用整个任务重来。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可并行性&lt;/strong&gt;：无依赖步骤并行，降低端到端延迟。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;拆分结果有三个验证标准：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;完备性&lt;/strong&gt;：所有步骤覆盖原始任务全部要求（逐项对照检查）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;独立性&lt;/strong&gt;：职责边界清晰，无重叠（防重复劳动和汇总矛盾）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可验证性&lt;/strong&gt;：每步有明确完成标准。好做法是拆分时同时写&amp;quot;验收标准&amp;quot;，步骤定义和验收标准成对出现。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;执行中的 &lt;strong&gt;Replan 机制&lt;/strong&gt;也很重要：每步执行后检查计划需不需要调整（比如发现竞品已停止运营，后续对比就没意义了）。折中做法是：不每步都触发 Replan，而是设触发条件（输出差异大/执行失败时才 Replan），避免每步多一次评估调用的开销。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;拆分粒度的&amp;quot;原子操作&amp;quot;标准：能写清晰函数签名的是原子，函数里还要分阶段的需要再拆。&lt;/li&gt;
&lt;li&gt;并行优化的前提是依赖稀疏——强依赖的步骤串行，并行空间为零，别强行并行。&lt;/li&gt;
&lt;li&gt;拆分时同步写&amp;quot;验收标准&amp;quot;，让每步可验证、可自动重试。&lt;/li&gt;
&lt;li&gt;自适应拆分（做不好才继续拆）比一开始就定死粒度更合理，开销与难度成正比。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第五章agent-记忆机制"&gt;第五章：Agent 记忆机制
&lt;/h2&gt;&lt;h3 id="51-短期记忆context-window"&gt;5.1 短期记忆（context window）
&lt;/h3&gt;&lt;p&gt;短期记忆就是 context window 里的 messages 列表，类比 LLM 的&amp;quot;工作台&amp;quot;。每步内容追加，每次调 LLM 传完整历史。任务结束清空，下次新任务桌面是空的。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShortTermMemory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="c1"&gt;# role: user/assistant/tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;进阶做法是&lt;strong&gt;结构化工作记忆&lt;/strong&gt;：给工作台划固定区域（当前任务目标 / 已确认中间结论 / 待验证假设），每步主动更新对应区域，替换过时内容，保持结构清晰，而不是让消息无限堆积。&lt;/p&gt;
&lt;h3 id="52-长期记忆向量数据库"&gt;5.2 长期记忆（向量数据库）
&lt;/h3&gt;&lt;p&gt;长期记忆跨任务持久，核心工具是&lt;strong&gt;向量数据库 + Embedding&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Embedding&lt;/strong&gt;：把文字转成几百到几千维的数字向量，捕捉&amp;quot;语义&amp;quot;。语义相近 → 向量空间距离近（类比 RGB 编码颜色，相近颜色 RGB 值也接近）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;向量数据库&lt;/strong&gt;：存数字向量，核心能力是&amp;quot;相似度检索&amp;quot;——给一个查询向量，找距离最近的几条（语义最相关的）。用 HNSW/IVF 等 ANN 索引加速，不用和每条都比较。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;chromadb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_or_create_collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;agent_memory&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_to_long_term&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;把内容存入长期记忆，metadata 记录时间/类型/重要程度&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;text-embedding-3-small&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;metadatas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# 时间/任务类型/重要程度/记忆类型，检索时可过滤&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;mem_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retrieve_memory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;语义检索最相关的几条记忆&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query_embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;text-embedding-3-small&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;n_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;documents&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;长期记忆的&lt;strong&gt;粒度&lt;/strong&gt;是个关键问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;太细&lt;/strong&gt;（每句话一条）：检索碎片化，只命中部分，信息不完整。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;太粗&lt;/strong&gt;（整次任务一条）：命中但相关内容只占一小部分，LLM 被无关内容干扰。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;合理粒度&lt;/strong&gt;：&amp;ldquo;一次完整交互&amp;quot;或&amp;quot;一个独立知识点/事件&amp;rdquo;。前者信息完整，后者如&amp;quot;用户偏好：Python，简洁风格，英文注释&amp;quot;打包一条结构化记录。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;记忆衰减&lt;/strong&gt;：给每条记忆加&amp;quot;新鲜度权重&amp;quot;，检索排序同时考虑语义相似度和时间新鲜度（越久越低）。相关性分数 = 语义相似度 × 时间衰减因子。或定期让 LLM 审查清理过时/矛盾的记忆。&lt;/p&gt;
&lt;h3 id="53-四层记忆机制设计"&gt;5.3 四层记忆机制设计
&lt;/h3&gt;&lt;p&gt;借用认知科学，工程上可以把记忆分为四层（从最短暂到最持久）：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;类比&lt;/th&gt;
&lt;th&gt;载体&lt;/th&gt;
&lt;th&gt;容量&lt;/th&gt;
&lt;th&gt;生命周期&lt;/th&gt;
&lt;th&gt;访问方式&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;感知记忆&lt;/td&gt;
&lt;td&gt;即时感觉&lt;/td&gt;
&lt;td&gt;当次输入&lt;/td&gt;
&lt;td&gt;极小&lt;/td&gt;
&lt;td&gt;单次调用&lt;/td&gt;
&lt;td&gt;即时访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;短期记忆&lt;/td&gt;
&lt;td&gt;工作记忆&lt;/td&gt;
&lt;td&gt;context window&lt;/td&gt;
&lt;td&gt;受 token 限制&lt;/td&gt;
&lt;td&gt;一次任务&lt;/td&gt;
&lt;td&gt;直接读取&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;长期记忆&lt;/td&gt;
&lt;td&gt;长期记忆&lt;/td&gt;
&lt;td&gt;向量/关系数据库&lt;/td&gt;
&lt;td&gt;无限&lt;/td&gt;
&lt;td&gt;持久&lt;/td&gt;
&lt;td&gt;语义检索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;实体记忆&lt;/td&gt;
&lt;td&gt;病历卡&lt;/td&gt;
&lt;td&gt;结构化存储&lt;/td&gt;
&lt;td&gt;无限&lt;/td&gt;
&lt;td&gt;持久&lt;/td&gt;
&lt;td&gt;精确查询&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;感知记忆&lt;/strong&gt;：当前调用的原始输入（用户消息、截图、文档），处理完消失。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;短期记忆&lt;/strong&gt;：context window 的 messages 列表，维持任务状态，任务结束清空。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;长期记忆&lt;/strong&gt;：跨任务，向量数据库语义检索。子类型包括：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;情节记忆&lt;/strong&gt;（Episodic）：具体事件经历（上次退款问题查了订单系统）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;语义记忆&lt;/strong&gt;（Semantic）：提炼的通用规律（用户是金融行业）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;程序记忆&lt;/strong&gt;（Procedural）：做事方法论 SOP（退款流程先查订单再核实支付）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实体记忆&lt;/strong&gt;：从对话中提炼的结构化事实（用户偏好 Python、预算 5 万），信息密度高，查询快，不受原始表述影响。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;设计记忆模块要回答三个核心问题：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 存什么？&lt;/strong&gt; 判断标准：&amp;ldquo;这条信息下次任务开始时知道，会让 Agent 做得更好吗？&amp;rdquo; 值得存：用户偏好习惯、关键结论决策、外部知识。不值得存：中间推理过程、工具原始数据、闲聊（存了反而稀释信噪比）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 怎么存？&lt;/strong&gt; 不一刀切全塞向量数据库，按信息类型选介质：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;语义检索内容（文档知识、对话摘要）→ 向量数据库 + embedding&lt;/li&gt;
&lt;li&gt;结构化偏好状态（语言偏好、项目配置）→ 关系数据库/Key-Value（精确查询快）&lt;/li&gt;
&lt;li&gt;整段文档 → 向量数据库配合 RAG&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;混合存储是主流&lt;/strong&gt;：结构化用关系数据库，非结构化用向量数据库。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;3. 什么时候取？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主动检索&lt;/strong&gt;：任务开始前用任务描述检索相关记忆，注入 system prompt 作背景知识。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;被动触发&lt;/strong&gt;：执行中需要特定知识时，把&amp;quot;查记忆&amp;quot;封装成 Tool 让 Agent 自己调。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实践&lt;/strong&gt;：session 开始主动检索加载偏好背景；执行中按需检索专业知识。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="54-记忆压缩的四种方法"&gt;5.4 记忆压缩的四种方法
&lt;/h3&gt;&lt;p&gt;短期记忆（context window）有硬上限，对话越长每次调用越贵。记忆压缩就是在保留关键信息的前提下，减少历史占用的 token。有四种方法，分别解决不同维度的问题：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方法一：滑动窗口（最简单最粗糙）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只保留最近 N 轮，超出从最老丢。&lt;/li&gt;
&lt;li&gt;优点：极简无额外开销。缺点：&lt;strong&gt;硬截断&lt;/strong&gt;，按时间一刀切，关键决策和闲聊同等对待。&lt;/li&gt;
&lt;li&gt;特性：&amp;ldquo;金鱼记忆&amp;rdquo;。适合短对话/历史不重要场景。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;方法二：摘要压缩（丢之前先提炼）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不直接丢，先 LLM 总结成精华摘要替换原文。&lt;/li&gt;
&lt;li&gt;类比：笔记本快满了，先把前半本要点整理成一页总结再收起来。&lt;/li&gt;
&lt;li&gt;代价：摘要会丢细节（LLM 按&amp;quot;重要性&amp;quot;省略，有些当时不重要后来需要的找不回）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;层级式摘要&lt;/strong&gt;：最近 10 轮原文，10-50 轮&amp;quot;中期摘要&amp;quot;，50 轮前&amp;quot;长期摘要&amp;quot;（类比会议纪要体系）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最常见工程组合：滑动窗口 + 摘要&lt;/strong&gt;——滑动窗口控总长，摘要负责丢弃前提炼。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;方法三：重要性过滤（按价值筛选，不按时间）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打破时间顺序，按内容实际价值决定去留：给每条打分，低于阈值淘汰。&lt;/li&gt;
&lt;li&gt;打分方式：规则打分（含&amp;quot;决定/确认/需求&amp;quot;关键词加分、被引用多加分；快但粗糙）或 LLM 打分（准确但开销大，批量清理时做）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;观察遮蔽&lt;/strong&gt;（Observation Masking）：不删除低分内容，构造 prompt 时选择性&amp;quot;隐藏&amp;quot;。当前写代码就跳过需求讨论，进入测试再显示测试相关。信息没真删，动态选&amp;quot;当前最需要看什么&amp;quot;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主动压缩&lt;/strong&gt;（Proactive Compression）：不等快满才压，每步执行后主动判断哪些中间过程可压缩（如搜索返回 2000 token 立刻压成 200 token 要点）。适合工具调用频繁的 Agent。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;方法四：结构化抽取（换载体存信息）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;质疑&amp;quot;对话文本是最佳载体吗&amp;quot;——很多场景有价值的是事实和状态，不是对话文字。&lt;/li&gt;
&lt;li&gt;主动提取关键信息存结构化字段（用户偏好 Python、预算 5 万、已确认方案 B）。&lt;/li&gt;
&lt;li&gt;类比医生病历（不存全程录音，存结构化档案）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;信息损失最小&lt;/strong&gt;，只要字段定义合理，重要信息精确保留。代价：开发成本最高，需预定义重要字段，通用性低。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;四种方法解决三个不同维度的问题，可以组合：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;历史太长怎么截&lt;/td&gt;
&lt;td&gt;滑动窗口（直接截）/ 摘要压缩（截前提炼）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内容不等价怎么挑&lt;/td&gt;
&lt;td&gt;重要性过滤（按价值，打破时间顺序）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;对话文本是不是最佳载体&lt;/td&gt;
&lt;td&gt;结构化抽取（换高效形式）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;实际系统多方法配合：重要性过滤筛低价值 → 摘要压缩处理剩余 → 关键信息结构化抽取。&lt;/p&gt;
&lt;p&gt;还有一个&lt;strong&gt;计算层&lt;/strong&gt;的互补手段：&lt;strong&gt;Prompt Caching&lt;/strong&gt;（Anthropic Claude 和 OpenAI 都支持）。背景是 LLM 每次请求需把输入所有 token&amp;quot;过一遍模型&amp;quot;（prefill），是延迟成本主要来源。固定 system prompt + 越来越长历史每次都重新计算。思路是：prompt 前缀在多次请求间一样，就把这部分计算结果缓存，下次前缀匹配直接复用。Anthropic 命中缓存 token 约为正常输入的 1/10。Agent 场景天然适合（system prompt + 长期记忆注入部分多轮不变）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意区分&lt;/strong&gt;：记忆压缩在&amp;quot;信息层&amp;quot;（决定哪些内容保留），Prompt Caching 在&amp;quot;计算层&amp;quot;（对已决定带入的内容减少重复计算）。两者是&lt;strong&gt;互补关系，非替代，可同时用&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="55-长短期记忆系统的存储与使用"&gt;5.5 长短期记忆系统的存储与使用
&lt;/h3&gt;&lt;p&gt;把两层记忆串起来，形成一个完整的&amp;quot;读 → 用 → 写&amp;quot;闭环：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_agent_with_memory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;long_term_memory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;short_term_memory&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 1. 任务开始前「读」：检索长期记忆，注入背景&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;relevant_memories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;long_term_memory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;你是一个智能助手。&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;相关历史信息：&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;relevant_memories&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;short_term_memory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;short_term_memory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 2. 执行中「用」：短期记忆全程工作（messages 追加）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;execute_task_with_short_term_memory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;short_term_memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 3. 任务结束后「写」：重要结论写入长期记忆，短期记忆清空&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_important&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;long_term_memory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;task_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;coding&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;timestamp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;short_term_memory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个&amp;quot;读-用-写&amp;quot;闭环是记忆系统的精髓：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;任务开始前&amp;quot;读&amp;quot;&lt;/strong&gt;：实体记忆取结构化偏好 + 长期记忆语义检索 → 注入 system prompt。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;任务执行中&amp;quot;用&amp;quot;&lt;/strong&gt;：短期记忆全程工作（messages 追加），需专业知识时临时检索注入。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;任务结束后&amp;quot;写&amp;quot;&lt;/strong&gt;：新偏好更新实体记忆，有价结论写长期记忆，短期记忆清空。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;记忆框架的趋势也值得关注：&lt;strong&gt;Mem0&lt;/strong&gt;（记忆管理独立服务层，&lt;code&gt;memory.add()&lt;/code&gt;/&lt;code&gt;memory.search()&lt;/code&gt;，底层自动做 embedding/去重/冲突消解）、&lt;strong&gt;Letta&lt;/strong&gt;（前身 MemGPT，灵感来自 OS 内存管理，三层：Core/Recall/Archival，Agent 自己通过工具调用管理）、&lt;strong&gt;Zep（Graphiti）&lt;/strong&gt;（引入&amp;quot;时间感知&amp;quot;，给记忆标&amp;quot;有效时间窗口&amp;quot;，自动识别过时记忆）。&lt;/p&gt;
&lt;p&gt;还有一个进阶话题是&lt;strong&gt;知识图谱让记忆产生关联&lt;/strong&gt;：向量检索是&amp;quot;一条一条&amp;quot;存取，记忆间独立；知识图谱用&amp;quot;实体→关系→实体&amp;quot;三元组存储，可沿关系链多跳推理。实践上是和向量数据库配合——向量负责模糊语义检索，知识图谱负责精确关系推理。&lt;/p&gt;
&lt;p&gt;记忆还需要定期&lt;strong&gt;整合升华&lt;/strong&gt;（从碎片到知识）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;去重&lt;/strong&gt;：语义相近的多条合并。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;冲突消解&lt;/strong&gt;：矛盾时保留时间更新的，标记旧的过期（时间戳关键）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;抽象提炼&lt;/strong&gt;（最有价值）：情节记忆 → 语义记忆，把多次具体经历喂 LLM 总结通用规律。&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;节奏：每次任务后轻量去重更新；每天/每周深度整理提炼。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;长期记忆的核心是 Embedding + 向量数据库语义检索，不是&amp;quot;存数据库靠关键词搜索&amp;quot;。&lt;/li&gt;
&lt;li&gt;记忆粒度不是越细越好——太细导致碎片化，&amp;ldquo;一次完整交互&amp;quot;或&amp;quot;一个独立知识点&amp;quot;是合理粒度。&lt;/li&gt;
&lt;li&gt;两层记忆的作用时机要分清：短期是执行中工作台（结束清空），长期是任务前检索注入/任务后写入沉淀。&lt;/li&gt;
&lt;li&gt;记忆压缩四种方法解决三个维度问题，可组合；Prompt Caching 是计算层互补手段，不替代信息层的压缩。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第六章agent-规划能力"&gt;第六章：Agent 规划能力
&lt;/h2&gt;&lt;h3 id="61-cot--tot--got-的演进"&gt;6.1 CoT → ToT → GoT 的演进
&lt;/h3&gt;&lt;p&gt;为什么需要规划能力？因为普通 LLM&amp;quot;一口气&amp;quot;生成答案，中间推理是隐式的，多步推导的误差在暗处累积（这是 Transformer next-token 预测机制决定的）。规划能力 = 把隐式推理显式化，不再&amp;quot;一步跳到答案&amp;rdquo;，而是&amp;quot;一步一步推到答案&amp;quot;。&lt;/p&gt;
&lt;p&gt;规划能力的演进路径是 &lt;strong&gt;CoT → ToT → GoT&lt;/strong&gt;，层层递进，每一层解决前一层的问题：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;机制&lt;/th&gt;
&lt;th&gt;解决的问题&lt;/th&gt;
&lt;th&gt;代价&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CoT&lt;/td&gt;
&lt;td&gt;要不要把推理显式化（要，减少跳步出错）&lt;/td&gt;
&lt;td&gt;几乎零成本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ToT&lt;/td&gt;
&lt;td&gt;走错方向怎么办（多探索几条路，边走边评估边剪枝）&lt;/td&gt;
&lt;td&gt;CoT 的 3-5 倍&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GoT&lt;/td&gt;
&lt;td&gt;不同路径中间结论能不能复用（树换图，支持结论汇聚）&lt;/td&gt;
&lt;td&gt;工程落地不成熟&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="62-tree-of-thoughts思维树"&gt;6.2 Tree of Thoughts（思维树）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;CoT（Chain of Thought，2022 Wei 等人）&lt;/strong&gt; 是最简单的：prompt 加一句&amp;quot;让我们一步步思考&amp;quot;，LLM 先写推理再给答案。有效原因：先输出的推理进入上下文，成为后续生成的依据（类比纸上演算数学题）。&lt;/p&gt;
&lt;p&gt;两种触发方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Zero-shot CoT&lt;/strong&gt;：直接加一句话，零成本即插即用，但不稳定。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Few-shot CoT&lt;/strong&gt;：给带推理过程的示例，效果更稳定，需准备示例占 token。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CoT 的根本局限：只有一条推理路径，一开始走错全错，&lt;strong&gt;无纠偏机制&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ToT（Tree of Thoughts）&lt;/strong&gt; 就是为了解决&amp;quot;走错方向&amp;quot;：把&amp;quot;一条链&amp;quot;变成&amp;quot;一棵树&amp;quot;——同时探索多条推理路径，边探索边评估边剪枝，选最优继续。&lt;/p&gt;
&lt;p&gt;三步循环：生成多个候选思路 → 评估每个可行性打分 → 选优深入、剪掉差的。类比：CoT 只想一个解法做到底；ToT 想三种思路，评估选最好的继续，另两条放弃。&lt;/p&gt;
&lt;p&gt;代价：多次 LLM 调用（多路径 × 多层深度 × 每层评估）。典型（每层 3 路径、搜 2-3 层）成本是 CoT 的 &lt;strong&gt;3-5 倍&lt;/strong&gt;；极端（深搜/更多路径/每步打分）可能 10 倍以上。&lt;/p&gt;
&lt;h3 id="63-graph-of-thoughts思维图"&gt;6.3 Graph of Thoughts（思维图）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;GoT（Graph of Thoughts）&lt;/strong&gt; 解决的是 ToT 的另一个局限：树形结构分支独立，中间结论无法互相借用。GoT 把&amp;quot;树&amp;quot;变成&amp;quot;图&amp;quot;——允许不同路径的中间结果合并、复用，一个节点可以接收多个前置节点的输出。&lt;/p&gt;
&lt;p&gt;例：研究竞品 A 和研究竞品 B 两条路径的结论，汇聚到&amp;quot;综合对比分析&amp;quot;节点（树结构每个节点只有一个父节点，难自然表达这种汇聚）。&lt;/p&gt;
&lt;p&gt;GoT 能建模更丰富的推理模式，更接近人类复杂思考。&lt;strong&gt;但落地复杂度很高，目前主要学术场景，生产极少&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="64-规划能力的实现方式"&gt;6.4 规划能力的实现方式
&lt;/h3&gt;&lt;p&gt;CoT/ToT/GoT 讲的是&amp;quot;怎么让 LLM 推理更好&amp;quot;，工程上真正常用的规划模式是 &lt;strong&gt;Plan-and-Execute&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Plan-and-Execute 三步流程 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 1. Planner（规划器） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 接收任务 → 生成步骤清单（只规划不执行） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 2. Executor（执行器） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 按清单逐步执行（工具调用/LLM 推理） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 3. Re-planner（重规划器） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 每步后回顾进展 → 判断计划是否适用 → 动态调整 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;为何需要&lt;/strong&gt;：CoT 边想边做无全局视角，复杂多工具任务易跑偏。Plan-and-Execute 先一次 LLM 建立全局视角，再后续调用逐步落地，规划执行分两阶段。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;与 ReAct 的关系&lt;/strong&gt;：ReAct 每步即时决策无提前规划；Plan-and-Execute 在 ReAct 基础上加全局规划。&lt;strong&gt;不是替代，常搭配&lt;/strong&gt;——ReAct 负责每步怎么执行，Plan-and-Execute 负责整体编排和动态调整。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;工程好处&lt;/strong&gt;：规划执行分离后，规划用强模型（GPT-4）保证方向，执行用快便宜模型提效，成本质量分别优化。LangGraph 内置支持这种模式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;工程选型&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CoT 几乎标配（加一句话零成本）。&lt;/li&gt;
&lt;li&gt;ToT 准确率要求高的复杂任务值得考虑（做好 3-5 倍成本准备）。&lt;/li&gt;
&lt;li&gt;GoT 工程落地不成熟，了解思想即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;典型误区：&amp;ldquo;CoT 就是规划能力&amp;rdquo;——CoT 只是最基础的实现手段，不是全部。&lt;/li&gt;
&lt;li&gt;ToT 不是&amp;quot;想更多&amp;quot;，而是&amp;quot;想多条路并评估剪枝&amp;quot;，成本是 CoT 的 3-5 倍，用之前做好预算。&lt;/li&gt;
&lt;li&gt;工程上优先用 Plan-and-Execute，它比 CoT/ToT/GoT 更贴近真实任务编排。&lt;/li&gt;
&lt;li&gt;规划用强模型、执行用便宜模型，是 Plan-and-Execute 最重要的成本优化手段。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第七章agent-反思机制"&gt;第七章：Agent 反思机制
&lt;/h2&gt;&lt;h3 id="71-反思的具体实现"&gt;7.1 反思的具体实现
&lt;/h3&gt;&lt;p&gt;反思的核心循环是 &lt;strong&gt;生成 → 评估 → 改进&lt;/strong&gt;（Self-Refine，Madaan 2023），类比&amp;quot;草稿 → 批阅 → 修改&amp;quot;，改完再审阅直到通过。&lt;/p&gt;
&lt;p&gt;评估 prompt（检查者角色找问题）有两个&lt;strong&gt;关键设计&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;给出明确检查维度&lt;/strong&gt;（事实/逻辑/完整性/表达），而非自由发挥——无方向评估会流于表面。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;必须有&amp;quot;PASS&amp;quot;机制&lt;/strong&gt;——给 LLM&amp;quot;够好了就停&amp;quot;的出口。没有则无限挑毛病，把原本对的改错。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;改进 prompt 里&lt;strong&gt;三样东西缺一不可&lt;/strong&gt;：原始任务 + 当前输出 + 评估意见。缺任何一个，改进就会变成无的放矢或偏离目标。&lt;/p&gt;
&lt;p&gt;两个 prompt 循环调用，直到 PASS 或超最大轮次强制退出（普通 for 循环，不依赖 LLM 自己判断停止）。&lt;/p&gt;
&lt;h3 id="72-反思与行动的关系"&gt;7.2 反思与行动的关系
&lt;/h3&gt;&lt;p&gt;反思有两个粒度，适用不同场景：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;粒度&lt;/th&gt;
&lt;th&gt;触发时机&lt;/th&gt;
&lt;th&gt;优点&lt;/th&gt;
&lt;th&gt;代价&lt;/th&gt;
&lt;th&gt;适合&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;步骤级&lt;/td&gt;
&lt;td&gt;每步工具调用/推理后立即检查&lt;/td&gt;
&lt;td&gt;错误早发现早纠正，不层层放大&lt;/td&gt;
&lt;td&gt;每步多一次调用，10 步任务可能调 20 次&lt;/td&gt;
&lt;td&gt;步骤强依赖、前步错后面全错&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;任务级&lt;/td&gt;
&lt;td&gt;整个任务完成后整体评估&lt;/td&gt;
&lt;td&gt;开销小（只多一次），能发现整体问题&lt;/td&gt;
&lt;td&gt;中途大问题到最后才发现&lt;/td&gt;
&lt;td&gt;步骤相对独立、整体质量重要（生成报告）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;步骤级反思防止&amp;quot;错误传播&amp;quot;，任务级反思发现&amp;quot;各步都对但结论矛盾/衔接不自然&amp;quot;的整体问题。两者不互斥，关键步骤用步骤级，整体用任务级。&lt;/p&gt;
&lt;h3 id="73-反思机制的闭环设计"&gt;7.3 反思机制的闭环设计
&lt;/h3&gt;&lt;p&gt;反思还有几个进阶机制：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;多 Agent 互评（他人审视 &amp;gt; 自我检查）&lt;/strong&gt;：专门设独立的 Critic Agent 审查执行 Agent 输出。为什么更好？类比代码 review——自己写自己看容易&amp;quot;视觉疲劳&amp;quot;，潜意识倾向认为逻辑正确。单 Agent 自我反思，评估者和生成者是同一模型，沿用生成时的内部逻辑，对自己的错误不敏感，容易陷入&amp;quot;自洽&amp;quot;。独立 Critic 没有这个包袱，唯一职责就是找问题，视角更客观。&lt;/p&gt;
&lt;p&gt;流程：执行 Agent 生成 → Critic 审查给批注 → 执行 Agent 修改 → Critic 再确认。适合质量要求非常高的场景（代码生成后测试 Agent 验证、报告后事实核查 Agent 交叉验证）。代价是多一个 Agent 的成本和复杂度。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reflexion&lt;/strong&gt;（Shinn 2023）：不仅反思当前输出，还把&amp;quot;失败经验&amp;quot;存下来，下次类似任务参考，避免重蹈覆辙。类比：Self-Refine 是&amp;quot;写完当场改&amp;quot;；Reflexion 是&amp;quot;把这次犯错记笔记本，下次写前先翻笔记&amp;quot;。引入&amp;quot;经验记忆&amp;quot;，适合重复执行类似任务的场景。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LATS&lt;/strong&gt;（Language Agent Tree Search，Zhou 2024）：反思 + 树搜索结合，MCTS 同时探索多条路径，每条路径执行后评估反思，反思结果作经验反馈后续探索。代价大，目前学术场景。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;辩论式反思&lt;/strong&gt;：多 Agent 互相辩论。正方提方案，反方专门挑毛病提反对意见，正方针对优化。对抗式比单方面审查更能暴露深层问题。偶用于高质量场景（商业决策分析、法律文本审查）。&lt;/p&gt;
&lt;h3 id="74-实践中的调参经验"&gt;7.4 实践中的调参经验
&lt;/h3&gt;&lt;p&gt;反思不是&amp;quot;万能 buff&amp;quot;，要清醒地权衡：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;值得开&lt;/strong&gt;：输出质量要求高、错误代价大的关键节点（最终报告、重要决策推理）；任务复杂 LLM 易遗漏细节。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不值得开&lt;/strong&gt;：简单直接任务（格式转换、简单问答）；实时性要求高（一次反思至少多一次调用，延迟可能从 1 秒变 3 秒）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;防死循环：必须设最大轮次（通常 2-3 轮），绝对不能依赖 LLM 自己判断停止&lt;/strong&gt;。LLM 会陷入&amp;quot;为了改而改&amp;quot;循环，每轮改动小但无实质进步。硬性轮次上限是唯一可靠退出机制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;整体代价清醒认知&lt;/strong&gt;：每轮反思含一次评估 + 一次改进，3 轮反思 = 额外 6 次 LLM 调用，延迟成本大幅增加。用在刀刃上，不是每步都做。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;反思不是&amp;quot;不满意就重新生成&amp;quot;（随机重试），而是&amp;quot;生成→评估→改进&amp;quot;有结构的闭环。&lt;/li&gt;
&lt;li&gt;评估 prompt 必须有明确检查维度 + PASS 机制，否则要么流于表面要么死循环。&lt;/li&gt;
&lt;li&gt;多 Agent 互评往往比自我反思更有效——独立 Critic 没有&amp;quot;自洽&amp;quot;包袱。&lt;/li&gt;
&lt;li&gt;反思最多 2-3 轮，硬性上限是唯一可靠的退出机制，绝不能依赖 LLM 自己判断停止。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第八章手搓-agent-vs-使用框架"&gt;第八章：手搓 Agent vs 使用框架
&lt;/h2&gt;&lt;h3 id="81-为什么有时候要手搓-agent"&gt;8.1 为什么有时候要手搓 Agent
&lt;/h3&gt;&lt;p&gt;框架（如 LangChain）的价值是真实的：封装重复工作（工具格式定义、解析工具调用、维护对话历史、失败重试、向量库接入），早期上手快，能把两周缩短到两天。POC 阶段几乎无副作用，框架很爽。&lt;/p&gt;
&lt;p&gt;但痛点随项目推进会浮现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第一个奇怪 bug&lt;/strong&gt;：你代码 50 行，stack trace 40 层，追到框架内部。不知道是自己的问题、框架版本变化、还是 callback 触发时机。类比老式车（打开引擎盖自己看漏油）vs 现代豪华车（一堆电子设备只能诊断仪扫）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;版本升级踩坑&lt;/strong&gt;：依赖升级时 LangChain 改了接口，代码报错，要么回滚要么改十几处。早期 breaking change 常见。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能优化隐性开销&lt;/strong&gt;：规模化时 profile 发现框架每次调用都在做你不需要的事（序列化中间结果、触发 callback、记录日志），高流量下累积成真实延迟和费用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="82-框架的局限性"&gt;8.2 框架的局限性
&lt;/h3&gt;&lt;p&gt;框架的核心局限在于&lt;strong&gt;抽象层让你离底层更远&lt;/strong&gt;。Anthropic 官方 Agent 构建指南也建议：不要一上来就用框架，先用最少抽象把核心逻辑跑通。&amp;ldquo;框架抽象层让你离底层更远，调试成本比省下的开发时间还高&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;类比：框架是&amp;quot;租房&amp;quot;（装修好直接住，但结构改不了，房东随时调政策）；手搓是&amp;quot;自建&amp;quot;（建得慢，但所有结构熟悉，改什么都能改）。&lt;/p&gt;
&lt;p&gt;对比一下两版代码就很清楚：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 框架版（简洁但黑盒）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AgentExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_openai_tools_agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_openai_tools_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AgentExecutor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;帮我查一下今天的天气&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# （AgentExecutor 新版已废弃，官方推荐迁移 LangGraph，印证升级痛点）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 手搓版（代码多但每步在眼前）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_turns&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tool_schemas&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;execute_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tool&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tool_call_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;工具 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 返回: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 随意加日志/监控/重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="83-手搓的核心要素"&gt;8.3 手搓的核心要素
&lt;/h3&gt;&lt;p&gt;手搓的核心优势是&lt;strong&gt;完全掌控&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;链路透明、可观测性好&lt;/strong&gt;：每行代码知道在干什么，任意位置加日志/断点/监控，无黑盒。线上出问题靠日志复现最快。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;精确裁剪、无多余开销&lt;/strong&gt;：只写需要的逻辑，无通用性包袱，优化空间完全在自己手里。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;稳定可控、不受框架升级影响&lt;/strong&gt;：自己接口不会突然变，依赖只有底层 LLM SDK 相对稳定。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="84-什么时候该手搓什么时候该用框架"&gt;8.4 什么时候该手搓，什么时候该用框架
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;选择&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;POC 快速验证 idea&lt;/td&gt;
&lt;td&gt;框架（速度优势真实）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;团队刚接触 Agent 开发&lt;/td&gt;
&lt;td&gt;框架（少踩基础坑）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;周边工具依赖框架生态&lt;/td&gt;
&lt;td&gt;框架&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;准备上生产，稳定性核心关切&lt;/td&gt;
&lt;td&gt;手搓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;流量上来，性能成本敏感&lt;/td&gt;
&lt;td&gt;手搓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;业务逻辑高度定制&lt;/td&gt;
&lt;td&gt;手搓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;需高可观测性&lt;/td&gt;
&lt;td&gt;手搓&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;最务实的折中方案：核心手写，周边借用。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;核心逻辑手写&lt;/strong&gt;（Agent 心脏）：工具调用循环、对话历史管理、错误处理重试、任务状态维护——百分百理解百分百掌控。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;周边工具借用&lt;/strong&gt;：LangSmith tracing、LlamaIndex 文档解析、向量库客户端——出问题一眼看出，不带来黑盒。&lt;/li&gt;
&lt;li&gt;类比盖房：自己设计核心结构承重墙，门锁插座水龙头买现成。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;真实项目的演进轨迹往往是：框架快速跑通验证方向 → 遇线上问题把关键部分替换手写 → 流量上来性能敏感核心全手写 → 框架只保留周边工具。&lt;/p&gt;
&lt;p&gt;判断信号：能清楚说出&amp;quot;框架在某处替我做了什么&amp;quot; → 理解它有掌控感；只调方法不知里面发生什么 → 黑盒需警惕。&lt;strong&gt;框架本身不是问题，&amp;ldquo;不理解就依赖&amp;quot;才是。&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不要一开口否定框架——POC 阶段它的速度优势是真实的。&lt;/li&gt;
&lt;li&gt;手搓的价值是&amp;quot;完全掌控&amp;rdquo;：可观测、稳定、可裁剪。&lt;/li&gt;
&lt;li&gt;最务实的是折中方案：核心逻辑手写（Agent 心脏），周边工具借用框架（不带来黑盒的部分）。&lt;/li&gt;
&lt;li&gt;判断该不该手搓的信号：能否清楚说出&amp;quot;框架在某处替我做了什么&amp;quot;。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第九章多-agent-系统"&gt;第九章：多 Agent 系统
&lt;/h2&gt;&lt;h3 id="91-什么是-multi-agent"&gt;9.1 什么是 Multi-Agent
&lt;/h3&gt;&lt;p&gt;Multi-Agent = 多个 Agent 协作完成任务，各有分工（搜索/写代码/评审）。&lt;strong&gt;价值不只是&amp;quot;多几个 AI&amp;quot;，背后有两个具体的工程问题驱动&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;单个 Agent 有两个硬限制：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;context window 大小限制&lt;/strong&gt;：复杂任务信息量一多就撑爆，早期内容&amp;quot;掉落&amp;quot;，Agent 遗忘。这是结构性上限，非努力优化能绕过。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;单点能力（专业度）问题&lt;/strong&gt;：什么都让一个 Agent 做，每件事都是泛才，精力分散。一个 Agent 既搜信息又写代码又测试又写文档，每件都不够专注，互相干扰。某环节出问题整条链路卡住，无隔离性。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Multi-Agent 的核心思路是&amp;quot;团队作战代替单打独斗&amp;quot;：按职能拆开，每个 Agent 只负责一件事，专心做好，做完传给下一个。关键好处：每个 Agent 的 context 完全隔离，工作台干净，只装自己那块信息，专业度更高；无依赖子任务可并行执行，整体速度提升；某环节出问题可隔离定位。&lt;/p&gt;
&lt;p&gt;三种协作模式：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;顺序流水线（Sequential Pipeline）&lt;/td&gt;
&lt;td&gt;A→B→C 依次处理，工厂流水线&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;并行扇出（Fan-out）&lt;/td&gt;
&lt;td&gt;调度者同时分发独立子任务给不同 Worker，并行执行，最后汇总&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;辩论/评审（Debate/Review）&lt;/td&gt;
&lt;td&gt;多 Agent 各给方案，裁判 Agent 或互相评审筛选最优解&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="92-single-agent-vs-multi-agent-选型"&gt;9.2 Single-Agent vs Multi-Agent 选型
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Single-Agent&lt;/strong&gt; 的本质：一个 LLM + 一套工具，跑决策循环。最大优势不只是&amp;quot;架构简单&amp;quot;，更核心是&lt;strong&gt;整条任务链路完全在掌控内&lt;/strong&gt;——任务怎么走、用什么工具、何时结束都在一处写清，出问题链路短好排查。类比一个人独立写博客，自己查资料想大纲写下来，单人更高效，沟通成本为零。&lt;/p&gt;
&lt;p&gt;Single-Agent 力不从心的&lt;strong&gt;三类任务&lt;/strong&gt;（此时 Multi-Agent 有真实价值）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;任务太长信息量太大，context 撑爆，Agent 遗忘。&lt;/li&gt;
&lt;li&gt;不同步骤需完全不同专业能力，什么都塞一个 Agent 每件都不专注。&lt;/li&gt;
&lt;li&gt;任务中有多个独立子任务可并行，单 Agent 只能一个个来。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;不属于这三类就用 Single-Agent，不要为&amp;quot;用新技术&amp;quot;强行引入 Multi-Agent。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;渐进式演进策略&lt;/strong&gt;（实用）：先 Single-Agent 跑起来，发现某环节成瓶颈（context 常撑满/某类子任务质量不行）再拆出来交专门 Worker Agent。&lt;strong&gt;不要一上来就设计五六个 Agent 的复杂系统&lt;/strong&gt;，可能连真正瓶颈都没搞清。从 Single-Agent 演进到 Multi-Agent 是自然过程，非一开始的架构决策。&lt;/p&gt;
&lt;p&gt;三方案对比：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;Single-Agent&lt;/th&gt;
&lt;th&gt;Multi-Agent（中心化）&lt;/th&gt;
&lt;th&gt;Multi-Agent（去中心化）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;架构复杂度&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context 压力&lt;/td&gt;
&lt;td&gt;全压一个&lt;/td&gt;
&lt;td&gt;各独立&lt;/td&gt;
&lt;td&gt;各独立，需额外共享协调状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;专业能力&lt;/td&gt;
&lt;td&gt;泛才&lt;/td&gt;
&lt;td&gt;专才分工&lt;/td&gt;
&lt;td&gt;专才分工&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;并行能力&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;td&gt;支持子任务并行&lt;/td&gt;
&lt;td&gt;支持并行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可控性&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;高（Orchestrator 统管）&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;调试难度&lt;/td&gt;
&lt;td&gt;容易&lt;/td&gt;
&lt;td&gt;中（按调度链路追踪）&lt;/td&gt;
&lt;td&gt;难（行为不可预测）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;工程实用性&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;低（主要学术研究）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;适用场景&lt;/td&gt;
&lt;td&gt;任务清晰复杂度适中&lt;/td&gt;
&lt;td&gt;需分工或并行的复杂任务&lt;/td&gt;
&lt;td&gt;学术探索&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="93-多-agent-通信方式消息传递-vs-共享状态"&gt;9.3 多 Agent 通信方式（消息传递 vs 共享状态）
&lt;/h3&gt;&lt;p&gt;Agent 间传递信息有两种方式：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;消息传递&lt;/strong&gt;（像发邮件）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agent 完成工作后把结果发到消息队列，下游 Agent 订阅感兴趣的消息取到再处理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;核心优势：解耦&lt;/strong&gt;——发送方不需知道谁在接收，接收方不需知道谁发送。&lt;/li&gt;
&lt;li&gt;缺点：需消息中间件维护机制，部署成本稍高。&lt;/li&gt;
&lt;li&gt;适合：Agent 间需独立运行、互相不感知。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;共享状态&lt;/strong&gt;（像共享白板）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;所有 Agent 读写同一状态对象，记录任务进展和中间结果。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;核心优势：直接&lt;/strong&gt;——前一步写进去后一步直接读。&lt;/li&gt;
&lt;li&gt;LangGraph 用此思路，贯穿所有 Agent 的 State，每个 Agent 执行完写入结果，下一个直接读。&lt;/li&gt;
&lt;li&gt;适合：各步骤依赖关系明确的流水线型任务。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;怎么选&lt;/strong&gt;：依赖强（前一步结果直接传后一步）→ 共享状态；希望解耦（互相不知存在）→ 消息传递。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;状态管理设计要点&lt;/strong&gt;（多 Agent 最易出 bug 处）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;状态结构分层&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;全局状态：所有 Agent 都需读取（用户原始请求、任务进展、最终输出）。&lt;/li&gt;
&lt;li&gt;局部状态：每个 Agent 自己的中间结果（搜索候选文档、代码草稿），不直接暴露给其他 Agent，避免信息污染。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;写入规则明确&lt;/strong&gt;：最简单可靠是&amp;quot;&lt;strong&gt;只追加不覆盖&lt;/strong&gt;&amp;quot;，每个 Agent 完成后追加而非修改已有字段。LangGraph State 更新机制即此思路——定义 schema，节点返回&amp;quot;增量更新&amp;quot;，框架合并到全局状态，不会互相覆盖。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误状态处理&lt;/strong&gt;：Agent 执行失败，错误信息也写入状态而非悄悄吞掉。后续 Agent/Orchestrator 读到错误状态才能正确决策（跳过/换 Agent 重试/终止）。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="94-路由策略静态规则-vs-llm-动态决策"&gt;9.4 路由策略（静态规则 vs LLM 动态决策）
&lt;/h3&gt;&lt;p&gt;Orchestrator 怎么决定叫谁？有静态和动态两种路由：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态路由&lt;/strong&gt;（提前写死规则）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;任务含搜索→Researcher&amp;quot;&amp;ldquo;步骤是代码写完→Reviewer&amp;rdquo;，找不到匹配→Orchestrator 兜底。&lt;/li&gt;
&lt;li&gt;像工厂流水线，每道工序完成后下一步固定。效率高、可预测、好调试。但覆盖不了没预料的情况。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;动态路由&lt;/strong&gt;（LLM 决策）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Orchestrator 把当前任务描述、已完成什么、可用 Agent 列表全告诉 LLM，让它判断&amp;quot;现在叫哪个 Agent&amp;rdquo;。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dynamic_route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;available_agents&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;当前任务状态：&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;task_context&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 可用的 Agent：&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;- &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;available_agents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 请根据当前进展，判断下一步应该交给哪个 Agent。只返回 Agent 名称，不需要解释。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;优点：灵活，能处理任何没预先设计的路径。缺点：每次路由多一次 LLM 调用（延迟成本增加），LLM 偶尔路由错，可预测性降低。实际还会加保护措施：校验返回名称是否在可用列表、设默认 fallback Agent、记录路由决策日志。&lt;/p&gt;
&lt;h3 id="95-orchestrator-中心化模式"&gt;9.5 Orchestrator 中心化模式
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Orchestrator&lt;/strong&gt;（交响乐指挥/总调度员/项目经理）是最特殊的 Agent：不做任何具体工作，只负责三件事——读懂大目标拆子任务、判断每个子任务交哪个 Worker、收集产出拼最终答案。&lt;/p&gt;
&lt;p&gt;Orchestrator 有三个变体：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变体&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;复杂度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;静态路由（Static Router）&lt;/td&gt;
&lt;td&gt;任务拆分分配规则预先定义&lt;/td&gt;
&lt;td&gt;简单可预测&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;动态规划（Dynamic Planner）&lt;/td&gt;
&lt;td&gt;Orchestrator 是 LLM，动态生成任务计划，可执行中调整&lt;/td&gt;
&lt;td&gt;中（大多数场景够用）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;自适应编排（Adaptive Orchestration）&lt;/td&gt;
&lt;td&gt;不仅动态规划，还根据 Worker 结果实时调整后续计划&lt;/td&gt;
&lt;td&gt;高（调试复杂）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Worker Agent 只关注自己那块，不需要知道整体任务和其他 Worker，拿指令做完返回结果退出，context 干净。&lt;/p&gt;
&lt;p&gt;中心化最大好处：每环节出问题能精准定位（报告不准→Researcher；分析逻辑错→Analyst；格式不对→Writer），顺着调度记录追根源。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;去中心化方案为什么&amp;quot;听起来灵活&amp;quot;却很少工程用？&lt;/strong&gt; 因为实际工程问题太多（三 Agent 场景为例）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;任务分配没协调（A 和 B 搜大量重叠内容，重复工作）。&lt;/li&gt;
&lt;li&gt;执行顺序没保证（C 不知 A/B 何时搜完，不知等多久）。&lt;/li&gt;
&lt;li&gt;失败没感知（A 中途出错，无中央调度收错误通知，B/C 还在跑，汇总出不完整结果但系统不知道）。&lt;/li&gt;
&lt;li&gt;没人确认&amp;quot;任务整体完成了&amp;quot;。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;类比无项目经理团队：每个人都能干，但没人协调时间节点和接口，交出互不兼容结果。&lt;strong&gt;生产环境几乎所有正经项目都选 Orchestrator 模式&lt;/strong&gt;。去中心化多停留在学术研究。&lt;/p&gt;
&lt;h3 id="96-多-agent-协作与动态切换"&gt;9.6 多 Agent 协作与动态切换
&lt;/h3&gt;&lt;p&gt;多 Agent 协作有三种主要模式（不互斥，复杂系统常混合）：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;流水线模式&lt;/td&gt;
&lt;td&gt;Agent 按固定顺序依次执行，前一个完成交下一个（工厂装配线）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;层级模式&lt;/td&gt;
&lt;td&gt;Orchestrator 分配任务收集结果，其他 Agent 各自执行子任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;协商模式&lt;/td&gt;
&lt;td&gt;多 Agent 无严格上下级，通过互相沟通辩论达成一致&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Handoff 模式&lt;/strong&gt;（Agent 间&amp;quot;接力棒&amp;quot;，OpenAI Swarm 框架推广）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不需中央 Orchestrator 决定&amp;quot;下一步找谁&amp;quot;，让当前执行 Agent 自己决定&amp;quot;我做完了，接下来交给谁&amp;quot;。接力赛跑，跑完自己那棒直接递接力棒。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;好处&lt;/strong&gt;：每个 Agent 对自己任务边界最清楚，由它决定下一步找谁往往比外部 Orchestrator 更准；无中央节点瓶颈，扩展性好。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺点&lt;/strong&gt;：无全局视角。A 交 B，B 觉得不是自己活交 C，C 又交回 A → 死循环。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;必须设计&lt;/strong&gt;：每个 Agent 职责边界清晰 + 防循环机制（记录任务经过哪些 Agent，重复经过同一 Agent 强制终止）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;工程上怎么用&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;最稳健：两种路由组合&lt;/strong&gt;——主流程静态路由（确定性节点切换写规则，保绝大多数稳定可预测），边缘情况才交 LLM 动态决策。静态路由&amp;quot;保底&amp;quot;，动态路由&amp;quot;兜住异常&amp;quot;，互补。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handoff&lt;/strong&gt;：适合 Agent 职责边界非常清晰、任务流向相对确定的场景。Agent 数量不多、输入输出接口明确 → 比 Orchestrator 简洁；数量多流向复杂 → 用 Orchestrator 统一调度避免交接成乱麻。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通信方式&lt;/strong&gt;：相对清晰流水线（明确前后依赖）→ 共享状态；需多 Agent 独立并行互不感知 → 消息传递。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="97-multi-agent-的工程挑战"&gt;9.7 Multi-Agent 的工程挑战
&lt;/h3&gt;&lt;p&gt;Multi-Agent 不是&amp;quot;多个 AI 效率更高&amp;quot;那么简单，它带来真实的工程挑战：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;通信开销&lt;/strong&gt;：Agent 间传递信息、Orchestrator 调度决策，都增加额外的 LLM 调用和延迟。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;状态一致性&lt;/strong&gt;：多 Agent 读写同一状态，设计不好易被意外覆盖或读脏数据（&amp;ldquo;只追加不覆盖&amp;quot;是最简单可靠的规则）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;调试复杂度&lt;/strong&gt;：行为路径不确定，出问题要顺着调度链路追根源，比 Single-Agent 难得多。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;成本控制&lt;/strong&gt;：每个 Agent 都是独立的 LLM 调用循环，多 Agent 系统的总 token 消耗和延迟会成倍增加。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;框架生态方面：CrewAI、LangGraph 封装了通信/调度/汇总基础设施。&lt;strong&gt;Microsoft Agent Framework（MAF）&lt;/strong&gt; 2025 年推出，合并了 Semantic Kernel（企业级）+ AutoGen（多 Agent 编排）为统一 SDK。选框架：微软技术栈生产优先 MAF；其他场景 CrewAI（上层易用）或 LangGraph（底层灵活）。&lt;/p&gt;
&lt;p&gt;协议趋势：&lt;strong&gt;A2A&lt;/strong&gt;（Agent2Agent，Google 2025 年 4 月提出）解决不同团队/框架开发的 Agent 间通信协作。之前每个框架自己通信方式，Agent 只能在同框架内协作。A2A 定义标准化通信协议，思路像微服务。目前已捐 Linux 基金会。但&lt;strong&gt;目前较早期&lt;/strong&gt;，实际生态&amp;quot;真正即插即用跨框架调用&amp;quot;未完全成熟，多为社区实现和示范项目。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;选型标准不能只说&amp;quot;任务复杂&amp;rdquo;，要说出三类具体场景（context 撑爆/需多专业/可并行）。&lt;/li&gt;
&lt;li&gt;生产环境几乎都选 Orchestrator 中心化模式——可控、可追踪、出问题能排查。去中心化主要在学术。&lt;/li&gt;
&lt;li&gt;状态管理用&amp;quot;只追加不覆盖&amp;quot;规则，避免多 Agent 互相覆盖。&lt;/li&gt;
&lt;li&gt;路由最稳健的组合：主流程静态路由保底 + 边缘情况动态路由兜底。&lt;/li&gt;
&lt;li&gt;不要一上来就设计五六个 Agent 的复杂系统，先 Single-Agent 跑通，遇瓶颈再渐进拆分。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="结尾"&gt;结尾
&lt;/h2&gt;&lt;h3 id="核心知识点回顾"&gt;核心知识点回顾
&lt;/h3&gt;&lt;p&gt;贯穿全文的核心原则，可以用八句话概括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;决策与执行分离&lt;/strong&gt;：模型是大脑只决策，代码真正执行（工具调用、ReAct 循环驱动）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;谁做决策是核心区分&lt;/strong&gt;：Tools 不决策、Agent 自主决策、Workflow 开发者写死决策。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可控性 &amp;gt; 灵活性&lt;/strong&gt;（生产环境）：能用 Workflow 就别用 Agent，Agentic Workflow 是主流。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;够用就好，别过度工程化&lt;/strong&gt;：先 ReAct 跑通，按需加 Plan-and-Execute / Reflection；先 Single-Agent，遇瓶颈再 Multi-Agent。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;完全掌控优于黑盒&lt;/strong&gt;：核心逻辑手写，周边工具借用框架。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工程取舍三维度&lt;/strong&gt;：任务复杂度、流程确定性、输出质量要求决定范式选型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;记忆读-用-写闭环&lt;/strong&gt;：任务前读记忆注入背景，执行中短期记忆维持状态，任务后写长期记忆沉淀。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;防失控机制必备&lt;/strong&gt;：最大循环次数/token 预算/超时（Agent）；最大反思轮次 2-3 轮（Reflection）；防循环记录（Handoff）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;用一张总览图把所有概念串起来：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 【Agent 本质】自主闭环（感知→规划→行动→再感知）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌───────────────┼───────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼ ▼ ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 【四大组件】 【三层结构】 【三大局限突破】
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; LLM(大脑) Tools(积木) 工具调用(突破知识冻结/不能行动)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 工具系统(手脚) Agent(决策者) 记忆机制(突破无持续状态)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 记忆系统(档案) Workflow(总指挥) 多步推理(自主纠错)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 规划模块(PM)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────┼──────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼ ▼ ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;【设计范式】 【推理模式】
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ReAct(边想边干) CoT(线性写推理)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Plan-and-Execute ToT(树形多路径)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(先规划再执行) GoT(图形可复用)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Reflection(质量buff)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├── 动态 Replan(计划遇意外调整)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── Reflexion(失败经验存记忆,错题本)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;【工程实践】
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;任务拆分(静态/动态/自适应) + 并行优化(DAG)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;记忆(四层) + 压缩(滑动窗口/摘要/重要性/结构化)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;规划能力(CoT→ToT→GoT + Plan-and-Execute)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;反思机制(生成→评估→改进, 步骤级/任务级, 多Agent互评)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;手搓vs框架(核心手写周边借用)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;【多Agent】
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Single vs Multi(context上限/专业度/并行)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;协作(消息传递/共享状态) + 切换(静态路由/动态路由/Handoff)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;中心化(Orchestrator) vs 去中心化(少用)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;协议(MCP管工具, A2A管Agent间通信)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="与其他主题的关联"&gt;与其他主题的关联
&lt;/h3&gt;&lt;p&gt;Agent 是整个 AI 工程知识体系的&lt;strong&gt;集大成者&lt;/strong&gt;。前面几篇文章讲的知识，在 Agent 这里汇聚成一个完整的自主系统：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LLM（大语言模型）&lt;/strong&gt;：Agent 的&amp;quot;大脑&amp;quot;，所有理解和决策的中枢。没有强 LLM，Agent 无从谈起——这正是 Agent 爆发的第一个条件。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAG（检索增强生成）&lt;/strong&gt;：Agent 长期记忆的本质就是&amp;quot;按需 RAG&amp;quot;——任务开始前检索相关记忆注入 context，和 RAG 检索文档注入 context 是同一个机制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具调用 / Function Calling&lt;/strong&gt;：Agent 突破&amp;quot;不能行动&amp;quot;的关键，也是&amp;quot;决策与执行分离&amp;quot;哲学的落地。MCP 协议标准化的正是这一层。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prompt Engineering&lt;/strong&gt;：Agent 的 System Prompt 是它的&amp;quot;岗位说明书&amp;quot;，调优占开发时间相当大比例。CoT/ToT 等&amp;quot;推理模式&amp;quot;本质也是 prompt 工程。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;框架（LangChain/LangGraph 等）&lt;/strong&gt;：降低 Agent 开发门槛的脚手架，但&amp;quot;核心手写、周边借用&amp;quot;才是生产环境的务实之道。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以说，&lt;strong&gt;理解了 Agent，就理解了 AI 工程的全貌&lt;/strong&gt;——它是 LLM + RAG + 工具调用 + 框架 + 规划 + 记忆 + 反思的融合体。任何一个环节的短板，都会成为 Agent 整体能力的瓶颈。&lt;/p&gt;
&lt;h3 id="进一步阅读资源"&gt;进一步阅读资源
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ReAct 原始论文&lt;/strong&gt;：Yao et al., &amp;ldquo;ReAct: Synergizing Reasoning and Acting in Language Models&amp;rdquo; (2022)——理解 Thought→Action→Observation 循环的理论源头。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reflexion 原始论文&lt;/strong&gt;：Shinn et al., &amp;ldquo;Reflexion: Language Agents with Verbal Reinforcement Learning from Multi-Aspect Feedback&amp;rdquo; (2023)——反思机制 + 经验记忆的奠基工作，HumanEval 80%→91% 的来源。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Self-Refine 论文&lt;/strong&gt;：Madaan et al., &amp;ldquo;Self-Refine: Iterative Refinement with Self-Feedback&amp;rdquo; (2023)——生成→评估→改进闭环的正式提出。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anthropic &amp;ldquo;Building Effective Agents&amp;rdquo;&lt;/strong&gt;：Anthropic 官方 Agent 构建指南，&amp;ldquo;能用 Workflow 就别用 Agent&amp;quot;原则的出处，强烈推荐。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MCP 规范&lt;/strong&gt;（Model Context Protocol）：Anthropic 提出的工具标准化协议，工具世界的&amp;quot;USB-C&amp;rdquo;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A2A 协议&lt;/strong&gt;（Agent2Agent）：Google 提出的 Agent 间通信协议，已捐 Linux 基金会。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LangGraph 文档&lt;/strong&gt;：生产级 Agent/Workflow 编排框架，Plan-and-Execute、共享状态等模式的参考实现。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Letta（MemGPT）&lt;/strong&gt;：灵感来自 OS 内存管理的记忆框架，三层记忆（Core/Recall/Archival）值得研究。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft Agent Framework（MAF）&lt;/strong&gt;：2025 年微软统一 SDK，合并 Semantic Kernel + AutoGen。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Agent 不是终点，而是 AI 工程从&amp;quot;单点能力&amp;quot;走向&amp;quot;自主系统&amp;quot;的起点。当 Agent 能自主闭环、能跨任务记忆、能多体协作，我们离真正的&amp;quot;通用 AI 助手&amp;quot;就更近了一步。理解本文的每一层，都是在为搭建那个&amp;quot;能干的私人助理&amp;quot;打地基。&lt;/p&gt;&lt;/blockquote&gt;</description></item><item><title>LangChain框架全解析——架构、组件与实战</title><link>https://blog.irudder.me/ai/ai-systematization/04-LangChain-Framework-Comprehensive-Guide.html</link><pubDate>Mon, 27 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/ai-systematization/04-LangChain-Framework-Comprehensive-Guide.html</guid><description>&lt;h1 id="langchain框架全解析架构组件与实战"&gt;LangChain框架全解析——架构、组件与实战
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;本篇为 AI 知识系列第 04 篇。素材整合自 LangChain 官方文档、腾讯云开发者社区、MyScale 技术博客、LangGraph 深度教程（2026 版）以及 Claude Code Skill 机制实战经验，并结合 2026 年最新实践整理而成。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="核心问题列表"&gt;核心问题列表
&lt;/h2&gt;&lt;p&gt;在正式开始之前，先把本篇要回答的核心问题列出来。带着问题读，效率更高。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;LangChain 到底是什么？&lt;/strong&gt; 它是一个模型，还是一个框架？为什么不提供自己的 LLM？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;Agent = Model + Harness&amp;rdquo; 是什么意思？&lt;/strong&gt; 这个公式为什么能决定整个生态的设计哲学？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LangChain 生态有哪些层次？&lt;/strong&gt; Deep Agents、LangChain、LangGraph、LangSmith 之间是什么关系？我该选哪一层？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;六大核心组件分别管什么？&lt;/strong&gt; Model I/O、Data Connection、Chains、Memory、Agents、Callbacks，它们如何协作？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LCEL 是什么？&lt;/strong&gt; 为什么说管道符语法是对传统 Chains 的现代化替代？Runnable 接口统一了什么？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LangGraph 为什么会出现？&lt;/strong&gt; 传统 Agent 循环哪里不够用？State、Nodes、Edges、Reducer 怎么协同工作？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;怎么实现人工干预？&lt;/strong&gt; interrupt() 和 Human-in-the-Loop 在生产中怎么落地？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LangSmith 怎么帮我们调试 Agent？&lt;/strong&gt; 追踪、评估、监控分别解决什么痛点？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LangServe 还能用吗？&lt;/strong&gt; 官方推荐的新部署方案是什么？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LangChain vs LlamaIndex vs CrewAI vs AutoGen，怎么选？&lt;/strong&gt; 有没有一棵决策树？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;什么时候不该用框架，而该手搓？&lt;/strong&gt; 框架的边界在哪里？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skill 机制和 LangChain 的工具有什么异同？&lt;/strong&gt; 从 Claude Code 的 Skill 实战中能学到什么？&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="引言"&gt;引言
&lt;/h2&gt;&lt;p&gt;2022 年底 ChatGPT 横空出世后，开发者们很快发现一个尴尬的事实：直接调用 LLM 的 API 其实很简单，一个 &lt;code&gt;requests.post&lt;/code&gt; 就能搞定；但要把它变成一个&amp;quot;产品&amp;quot;，却要处理无数工程问题——提示词怎么管理？长对话的上下文怎么保持？怎么让模型调用外部工具？怎么把检索到的文档喂给模型？怎么调试一个跑了十步才报错的 Agent？&lt;/p&gt;
&lt;p&gt;这些问题，每一个单独看都不难，但叠在一起就成了拦路虎。LangChain 就是在这个背景下诞生的：它不提供模型，而是提供一整套&lt;strong&gt;标准化抽象&lt;/strong&gt;，让你把&amp;quot;模型 + 提示词 + 工具 + 记忆 + 流程编排&amp;quot;像搭积木一样组合起来。&lt;/p&gt;
&lt;p&gt;经过几年迭代，LangChain 已经从一个单一库，长成了一个包含 Deep Agents、LangChain、LangGraph、LangSmith、LangDeployment 的完整产品体系。它经历了从&amp;quot;大而全的 Chain&amp;quot;到&amp;quot;LCEL 管道符语法&amp;quot;再到&amp;quot;LangGraph 图编排&amp;quot;的范式演进，也经历了 LangServe 弃用、LangGraph Platform 更名等架构调整。理解这个演进过程，比记住某个 API 更重要——因为框架会变，但背后解决问题的思路是稳定的。&lt;/p&gt;
&lt;p&gt;本篇将从定位、生态、组件、语法、编排、调试、部署、选型、最佳实践九个维度，把 LangChain 体系彻底拆解一遍。每个概念都会配 Python 代码和 ASCII 架构图，每章末尾有实践要点小结。读完之后，你不仅知道&amp;quot;怎么用&amp;quot;，更知道&amp;quot;为什么这么设计&amp;quot;以及&amp;quot;什么时候不该用&amp;quot;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第一章-langchain-概述与定位"&gt;第一章 LangChain 概述与定位
&lt;/h2&gt;&lt;h3 id="11-什么是-langchain"&gt;1.1 什么是 LangChain
&lt;/h3&gt;&lt;p&gt;LangChain 是一个用于构建大语言模型（LLM）应用的多功能框架。这里有一个关键认知必须先纠正：&lt;strong&gt;LangChain 不提供自己的 LLM&lt;/strong&gt;。它不训练模型，也不卖模型，而是提供了一个&lt;strong&gt;标准接口&lt;/strong&gt;，让你能用统一的 API 调用 OpenAI、Anthropic、Google、Ollama、Azure、AWS Bedrock、HuggingFace 等几十家模型提供商的模型。&lt;/p&gt;
&lt;p&gt;这意味着什么？意味着你可以今天用 GPT-5.5，明天切换到 Claude Sonnet，后天换成本地部署的 Ollama 模型，而你的业务代码几乎不用改。这种&amp;quot;模型可替换性&amp;quot;是 LangChain 最早也是最持久的价值主张。&lt;/p&gt;
&lt;p&gt;它的核心定位用一句话概括：&lt;strong&gt;Agent 框架&lt;/strong&gt;——提供模型、工具、Agent 的标准化抽象，让开发者高效地设计适用于各种用例的定制解决方案。&lt;/p&gt;
&lt;h3 id="12-核心理念agent--model--harness"&gt;1.2 核心理念：Agent = Model + Harness
&lt;/h3&gt;&lt;p&gt;这是理解整个 LangChain 生态的钥匙。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Agent = Model + Harness │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌──────────┐ ┌──────────────────────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Model │ + │ Harness（运行框架） │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ (大脑) │ │ 提示词 + 工具 + 中间件 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └──────────┘ └──────────────────────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ GPT-5.5 create_agent 提供的部分 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Claude │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Gemini 模型循环周围的一切 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;LangChain 官方对此的解释是：&lt;code&gt;create_agent&lt;/code&gt; 提供的是一个&lt;strong&gt;最小化、高度可配置的运行框架（harness）&lt;/strong&gt;。这个框架是&amp;quot;模型循环周围的一切&amp;quot;——提示词（prompt）、工具（tools），以及任何塑造行为的中间件（middleware）。&lt;/p&gt;
&lt;p&gt;换句话说，模型负责&amp;quot;思考&amp;quot;，harness 负责把思考过程组织成一个可运行的循环：给模型喂什么提示、模型说要调什么工具就去调、调完结果怎么拼回提示、什么时候该停。这个循环的结构是固定的，但里面填什么内容是高度可配置的。&lt;/p&gt;
&lt;p&gt;为什么要强调&amp;quot;从基础原语开始组合&amp;quot;？因为 LangChain 的设计哲学是：不给你一个黑盒 Agent，而是给你积木。你从基础原语（模型接口、工具定义、提示模板）开始，组合出你的用例所需的确切能力。这与后面要讲的 Skill 机制理念相通——好的抽象不是把复杂性藏起来，而是让你能精确控制每一层。&lt;/p&gt;
&lt;h3 id="13-框架定位"&gt;1.3 框架定位
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心模块&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;六大核心模块：Model I/O、Data Connection、Chains、Memory、Agents、Callbacks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;抽象层级&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;中等（组件化，不像 LangGraph 那么底层，也不像 Deep Agents 那么开箱即用）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心能力&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;模型/工具/链/Agent 抽象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;使用方式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可独立使用，也可与 LangGraph 组合&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;适合场景&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;快速构建 Agent 和 LLM 应用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;模型支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;OpenAI、Anthropic、Google、Ollama、Azure、AWS Bedrock、HuggingFace 等&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="14-典型应用场景"&gt;1.4 典型应用场景
&lt;/h3&gt;&lt;p&gt;LangChain 在以下场景表现出色：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;聊天机器人应用&lt;/strong&gt;：长对话上下文保持、多轮记忆&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文本生成与创造性生成&lt;/strong&gt;：文案、代码、故事&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;查询回答（RAG）&lt;/strong&gt;：检索增强生成，让模型基于你的私有数据回答&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;语言翻译&lt;/strong&gt;：多语言转换&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自主操作和复杂问题解决（Agent）&lt;/strong&gt;：模型自主决策调用工具，完成多步骤任务&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;情感分析、内容生成等 NLP 任务&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="15-一个最小示例"&gt;1.5 一个最小示例
&lt;/h3&gt;&lt;p&gt;在深入组件之前，先看一个最小的 LangChain 应用长什么样，建立直觉：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 定义提示模板&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;你是一位资深 &lt;/span&gt;&lt;span class="si"&gt;{role}&lt;/span&gt;&lt;span class="s2"&gt;，请用通俗易懂的方式解释 &lt;/span&gt;&lt;span class="si"&gt;{concept}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 选择模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 定义输出解析器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. 用管道符组合成链&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 5. 调用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;物理学家&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;concept&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;量子纠缠&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这五行核心代码就完成了一个&amp;quot;提示词 → 模型 → 解析输出&amp;quot;的完整链路。后续每一章，我们都会在这个骨架上叠加更多能力。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;第一章实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;记住 &lt;code&gt;Agent = Model + Harness&lt;/code&gt;，这是理解整个生态的钥匙。你的工作大多是&amp;quot;配置 harness&amp;quot;，而不是改模型。&lt;/li&gt;
&lt;li&gt;LangChain 的核心价值是&amp;quot;标准接口 + 可组合积木&amp;quot;，不要把它当黑盒用，要理解每一块积木的职责。&lt;/li&gt;
&lt;li&gt;模型可替换性是第一价值主张：业务代码与具体模型解耦，今天用 GPT，明天能无痛切 Claude。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第二章-生态系统全景"&gt;第二章 生态系统全景
&lt;/h2&gt;&lt;h3 id="21-五层架构"&gt;2.1 五层架构
&lt;/h3&gt;&lt;p&gt;LangChain 早已不是一个单一库，而是一个分层的产品体系。从上到下，抽象级别递减，灵活性递增：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LangChain 产品体系（五层） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────┬───────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Deep Agents │ 开箱即用的 Agent，最上层抽象 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ (最高层) │ 含自动上下文压缩、虚拟文件系统、子Agent │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────┼───────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LangChain │ Agent 框架：模型/工具/Agent 抽象 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ (框架层) │ create_agent，高度可定制的 harness │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────┼───────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LangGraph │ 编排运行时：持久化/流式/人工干预 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ (运行时层) │ 低级图结构，有状态多步骤工作流 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────┼───────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LangSmith │ 可观测性平台：追踪/评估/监控/部署 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ (可观测层) │ 框架无关，能追踪任何 Agent 技术栈 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────┼───────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LangDeployment │ 部署方案：将 Chain/Graph 封装为 API │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ (部署层) │ Server + Studio + Cloud + 自托管 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────┴───────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="22-各组件职责划分"&gt;2.2 各组件职责划分
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;组件&lt;/th&gt;
&lt;th&gt;定位&lt;/th&gt;
&lt;th&gt;职责&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deep Agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;最高层抽象&lt;/td&gt;
&lt;td&gt;开箱即用的 Agent，含自动上下文压缩、虚拟文件系统、子 Agent 生成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LangChain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent 框架&lt;/td&gt;
&lt;td&gt;模型/工具/链/Agent 抽象，&lt;code&gt;create_agent&lt;/code&gt; 高度可定制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LangGraph&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;编排运行时&lt;/td&gt;
&lt;td&gt;状态管理/流程控制/持久化/人工干预，低级图结构&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LangSmith&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可观测性平台&lt;/td&gt;
&lt;td&gt;追踪/调试/评估/监控/部署，框架无关&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LangServe / LangDeployment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;部署方案&lt;/td&gt;
&lt;td&gt;将 Chain/Graph 封装为稳定 API 服务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;理解这五层的关键在于：&lt;strong&gt;它们是可组合的，不是互斥的&lt;/strong&gt;。你可以只用 LangChain 搭一个简单 Chain；也可以用 LangChain + LangGraph 搭一个有状态多 Agent 工作流；无论哪种，都建议挂上 LangSmith 做追踪；最后用 LangDeployment 部署成 API。&lt;/p&gt;
&lt;h3 id="23-层级关系图"&gt;2.3 层级关系图
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 你的应用
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌────────────┼────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼ ▼ ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Deep Agents LangChain LangGraph ← 选择一层作为主体
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └────────────┼────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; LangSmith ← 横切所有层（追踪/评估）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; LangDeployment ← 最后部署成 API
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 生产环境
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="24-选型建议官方推荐"&gt;2.4 选型建议（官方推荐）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Deep Agents&lt;/strong&gt;：需要&amp;quot;开箱即用&amp;quot;的 Agent（含自动上下文压缩、虚拟文件系统、子 Agent 生成），不想自己搭 harness&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LangChain（&lt;code&gt;create_agent&lt;/code&gt;）&lt;/strong&gt;：需要高度可定制的 harness，轻松适配用例和数据&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LangGraph&lt;/strong&gt;：低级编排框架，用于结合确定性和 Agent 工作流的高级需求&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LangSmith&lt;/strong&gt;：追踪、调试和评估用任何框架构建的 Agent（包括非 LangChain 的）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一个常见误区是&amp;quot;先选最高层的 Deep Agents，省事&amp;quot;。但开箱即用的代价是灵活性低。如果你的业务流程有特殊的确定性步骤（比如必须先查数据库、再调审核、最后发邮件），Deep Agents 的自动循环可能反而不如 LangGraph 的图结构可控。选型的核心问题是：&lt;strong&gt;你的工作流有多需要确定性控制？&lt;/strong&gt; 越需要确定性，越往下层走。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;第二章实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;五层不是&amp;quot;高低优劣&amp;quot;，而是&amp;quot;抽象级别&amp;quot;。上层省事但灵活度低，下层灵活但要多写代码。&lt;/li&gt;
&lt;li&gt;LangSmith 是横切的，不管你用哪层都建议挂上，追踪数据是后续优化的基础。&lt;/li&gt;
&lt;li&gt;选型先问&amp;quot;确定性 vs 自主性&amp;quot;的比例，再决定用哪一层做主体。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第三章-核心组件详解"&gt;第三章 核心组件详解
&lt;/h2&gt;&lt;p&gt;LangChain 框架的核心模块主要有六个：&lt;strong&gt;模型输入输出（Model I/O）、数据连接（Data Connection）、链（Chains）、记忆（Memory）、代理（Agents）和回调（Callbacks）&lt;/strong&gt;。这六个模块覆盖了一个 LLM 应用从&amp;quot;输入&amp;quot;到&amp;quot;输出&amp;quot;到&amp;quot;记忆&amp;quot;到&amp;quot;自主行动&amp;quot;的完整链路。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LangChain 六大核心组件 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Model I/O│──▶│ Chains │──▶│ Agents │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ (输入输出)│ │ (链式组合) │ │ (自主决策) │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └──────────┘ └──────────────┘ └──────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ▼ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Memory │ │Data Connection│ │ Callbacks │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ (记忆) │ │ (数据连接) │ │ (回调) │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └──────────┘ └──────────────┘ └──────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="31-模型输入输出model-io"&gt;3.1 模型输入输出（Model I/O）
&lt;/h3&gt;&lt;p&gt;任何语言模型应用程序的核心元素都是&lt;strong&gt;模型&lt;/strong&gt;。Model I/O 模块是与模型交互的构建块，包含四个子组件。&lt;/p&gt;
&lt;h4 id="311-语言模型language-models"&gt;3.1.1 语言模型（Language Models）
&lt;/h4&gt;&lt;p&gt;LangChain 为两种类型的模型提供统一接口：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LLM&lt;/strong&gt;：将文本字符串作为输入并返回文本字符串的模型（传统补全模型）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ChatModel&lt;/strong&gt;：将聊天消息列表作为输入并返回聊天消息的模型（对话模型）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.messages&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SystemMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AIMessage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ChatModel（推荐，现代模型都是对话模型）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chat_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 方式一：直接传字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chat_model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;什么是 RAG？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 方式二：传消息列表（更灵活，能设定 system 角色）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SystemMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;你是一位耐心的 AI 老师，回答要简洁准确&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;什么是 RAG？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chat_model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Token 用量: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;usage_metadata&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;聊天模型在底层使用语言模型，但暴露的接口不同：它们不暴露&amp;quot;文本输入文本输出&amp;quot;的 API，而是把聊天消息（ChatMessage）列表作为输入输出。这种设计让多轮对话和 system/human/ai 角色区分变得自然。&lt;/p&gt;
&lt;p&gt;LangChain 支持按照 LLM 接口标准集成自定义的语言模型，提供统一的 API 调用不同的模型。切换模型只需改一行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 切换到 Anthropic Claude&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_anthropic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatAnthropic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chat_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatAnthropic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;claude-sonnet-4-20250514&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 切换到本地 Ollama&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_ollama&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOllama&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chat_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOllama&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;llama3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 业务代码完全不用改&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="312-提示模板prompt-templates"&gt;3.1.2 提示模板（Prompt Templates）
&lt;/h4&gt;&lt;p&gt;提示模板是预定义的配方，用于为语言模型生成提示。模板可能包括说明、少量示例（few-shot）、适合给定任务的特定上下文和问题。&lt;/p&gt;
&lt;p&gt;两种主要类型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;PromptTemplate&lt;/code&gt;&lt;/strong&gt;：用于生成字符串提示，使用 Python 的字符串格式&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;ChatPromptTemplate&lt;/code&gt;&lt;/strong&gt;：用于生成聊天提示作为聊天消息列表&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 字符串模板（用于 LLM）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;string_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;请把以下文本翻译成&lt;/span&gt;&lt;span class="si"&gt;{language}&lt;/span&gt;&lt;span class="s2"&gt;：&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{text}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 聊天模板（用于 ChatModel，推荐）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chat_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_messages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;你是一位专业的&lt;/span&gt;&lt;span class="si"&gt;{role}&lt;/span&gt;&lt;span class="s2"&gt;，回答要&lt;/span&gt;&lt;span class="si"&gt;{style}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{question}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 渲染&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;formatted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chat_prompt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;数据科学家&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;style&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;深入浅出&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;解释什么是梯度下降&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# -&amp;gt; messages=[SystemMessage(&amp;#39;你是一位专业的数据科学家...&amp;#39;), HumanMessage(&amp;#39;解释什么是梯度下降&amp;#39;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;提示模板的目标是&lt;strong&gt;使跨不同模型重用提示变得容易&lt;/strong&gt;，将提示工程与模型调用分开。这比你每次调用都手拼字符串要好得多——模板可以版本管理、A/B 测试、团队共享。&lt;/p&gt;
&lt;h4 id="313-示例选择器example-selectors"&gt;3.1.3 示例选择器（Example Selectors）
&lt;/h4&gt;&lt;p&gt;允许用户为模型提供示例输入和输出（few-shot），以帮助模型学习执行特定任务。用途包括训练新模型、调优现有模型、测试模型、说明模型能力、调试模型、控制模型行为。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.example_selectors&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SemanticSimilarityExampleSelector&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FewShotChatMessagePromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_chroma&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 准备示例库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;examples&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;高兴&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;output&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;悲伤&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;高大&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;output&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;矮小&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;精力充沛&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;output&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;无精打采&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;简单&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;output&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;复杂&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;快&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;output&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;慢&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 语义相似度选择器：根据输入动态选择最相关的示例&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;example_selector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SemanticSimilarityExampleSelector&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_examples&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 构建 few-shot 提示&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;few_shot_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FewShotChatMessagePromptTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;example_selector&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;example_selector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;example_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_messages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{input}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ai&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{output}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 组合成完整提示&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;final_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_messages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;给出输入词的反义词&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;few_shot_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{input}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;final_prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;热情&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="314-输出解析器output-parsers"&gt;3.1.4 输出解析器（Output Parsers）
&lt;/h4&gt;&lt;p&gt;语言模型输出内容是文本格式，但开发 AI 应用时希望能拿到格式化的内容（如目标对象、JSON、数组等）。输出解析器用于格式化语言模型返回的结果。&lt;/p&gt;
&lt;p&gt;一个输出解析器必须实现两种必要的方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;get_format_instructions&lt;/code&gt;&lt;/strong&gt;：返回要求语言模型应该返回什么格式内容的提示词&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;parse&lt;/code&gt;&lt;/strong&gt;：将模型返回的内容解析为目标格式&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可选方法：&lt;strong&gt;&lt;code&gt;parse_with_prompt&lt;/code&gt;&lt;/strong&gt;：接受响应和提示，处理重试或修复输出。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PydanticOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 定义期望的输出结构&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MovieReview&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;电影标题&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;评分 1-10&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;一句话影评&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pros&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;优点列表&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;缺点列表&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 创建解析器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PydanticOutputParser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pydantic_object&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MovieReview&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 解析器会自动生成格式说明，注入到提示里&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_messages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;你是一位影评人。请按指定格式输出影评。&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{format_instructions}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;human&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;请评价电影：&lt;/span&gt;&lt;span class="si"&gt;{movie}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;format_instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_format_instructions&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 拿到的是结构化对象，不是字符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;review&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;movie&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;盗梦空间&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;电影: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;review&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 评分: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;review&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/10&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;优点: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;review&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pros&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;输出解析器允许定义期望的输出结构（如 Pydantic 模型），然后解析语言模型的文本输出来填充该结构，可进行验证、访问特定字段等。这把&amp;quot;模型输出的是文本&amp;quot;这个根本性摩擦给抹平了。&lt;/p&gt;
&lt;h4 id="model-io-完整流程图"&gt;Model I/O 完整流程图
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 用户输入 提示模板 模型 输出解析器
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼ ▼ ▼ ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {topic:&amp;#34;RAG&amp;#34;} → ChatPromptTemplate → ChatOpenAI → StrOutputParser
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (注入变量+格式说明) (调用 LLM) (解析为 str/JSON/对象)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 结构化结果
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="32-数据连接data-connection"&gt;3.2 数据连接（Data Connection）
&lt;/h3&gt;&lt;p&gt;在许多 LLM 应用中，用户特定的数据不在模型的训练集中，这需要通过检索增强生成（RAG）实现。RAG 的主要方法是检索外部数据，并在生成步骤中传递给 LLM。LangChain 为 RAG 应用程序提供了完整的构建块。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌───────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ RAG 数据连接全流程 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │Document │──▶│Document │──▶│Text │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │Loaders │ │Transformers│ │Embedding │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │(加载) │ │(拆分/转换) │ │Models │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └────────────┘ └────────────┘ └────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │Vector │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │Stores │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │(存储+检索) │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌────────────┐ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │Retrievers │◀────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │(检索接口) │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Indexing API（避免重复写入/重算嵌入） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└───────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="321-文档加载器document-loaders"&gt;3.2.1 文档加载器（Document Loaders）
&lt;/h4&gt;&lt;p&gt;将来自不同数据源的非结构化文本加载为文档对象（含文本片段和元数据）。支持简单文本文件、网页内容、YouTube 视频转录、PDF 等。提供 &lt;code&gt;load&lt;/code&gt; 方法，支持&amp;quot;延迟加载&amp;quot;以节省内存。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_community.document_loaders&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;TextLoader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WebBaseLoader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PyPDFLoader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DirectoryLoader&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 加载单个文本文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TextLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./knowledge_base.txt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 加载网页&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;web_loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebBaseLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://example.com/article&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;web_docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;web_loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 加载 PDF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pdf_loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PyPDFLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./report.pdf&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pdf_docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pdf_loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 每页一个 Document&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 批量加载目录下所有文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;dir_loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DirectoryLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./docs/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;**/*.pdf&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loader_cls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PyPDFLoader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;all_docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dir_loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;共加载 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 个文档&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;第一个文档元数据: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;all_docs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="322-文档转换器document-transformers"&gt;3.2.2 文档转换器（Document Transformers）
&lt;/h4&gt;&lt;p&gt;对加载的文档进行转换和处理，主要包括文本拆分器、冗余过滤器、元数据提取器、多语言转换器、对话转换器。其中最常用的是&lt;strong&gt;文本拆分器&lt;/strong&gt;，它将长文本拆分成语义上相关的小块，适应上下文窗口限制。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_text_splitters&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 递归字符拆分器：优先按段落、然后按句子、最后按字符拆分&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;splitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 每块最大 1000 字符&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chunk_overlap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 块之间重叠 200 字符，保持上下文连贯&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;separators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;！&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;，&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;splitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;拆分前 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 个文档 → 拆分后 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 个块&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="323-文本嵌入模型text-embedding-models"&gt;3.2.3 文本嵌入模型（Text Embedding Models）
&lt;/h4&gt;&lt;p&gt;将文本转换为向量表示，用于文本检索（语义搜索）、信息推荐、知识挖掘、语义匹配。LangChain 通过统一的 API 调用不同的文本嵌入模型。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;text-embedding-3-small&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 嵌入单条文本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embed_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LangChain 是一个 LLM 应用框架&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;向量维度: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 批量嵌入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;texts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;RAG 是检索增强生成&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Agent 能自主调用工具&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vectors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embed_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="324-矢量存储vector-stores"&gt;3.2.4 矢量存储（Vector Stores）
&lt;/h4&gt;&lt;p&gt;存储和搜索非结构化数据的最常见方法之一是嵌入它并存储生成的嵌入向量，然后在查询时嵌入查询并检索&amp;quot;最相似&amp;quot;的嵌入向量。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_chroma&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 从文档块创建向量库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vectorstore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;persist_directory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./chroma_db&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 持久化到磁盘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 相似度搜索&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;similarity_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;LangChain 的核心组件有哪些？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 返回最相似的 3 个&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 带分数的搜索&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;results_with_score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;similarity_search_with_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;什么是 RAG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results_with_score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;分数: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;.4f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="325-检索器retrievers"&gt;3.2.5 检索器（Retrievers）
&lt;/h4&gt;&lt;p&gt;一种用于响应非结构化查询的接口，返回符合查询要求的文档。相较于矢量存储，检索器更加通用——它是一个接口，任何&amp;quot;给查询返回文档&amp;quot;的逻辑都能包装成检索器。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.retrievers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseRetriever&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 最简单：把向量库转成检索器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;search_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;similarity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 也可用 mmr（最大边际相关性，去重）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;search_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;k&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LangChain 的 Memory 组件&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;检索到 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 个相关文档&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 自定义检索器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomRetriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseRetriever&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_get_relevant_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 这里可以混用：向量检索 + 关键词检索 + 规则过滤&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;similarity_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;LangChain 提供矢量检索器、文档检索器、网站研究检索器等，可自定义检索逻辑。主要作用是提高问答系统的覆盖面、提供额外的上下文、支持开放域问答。&lt;/p&gt;
&lt;h4 id="326-索引indexing"&gt;3.2.6 索引（Indexing）
&lt;/h4&gt;&lt;p&gt;索引 API 能够将来自各种源的文档同步到矢量存储中，避免不必要的重复写入和重新计算嵌入，节省时间和金钱，改善矢量搜索结果。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.indexes&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SQLRecordManager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 记录管理器：追踪哪些文档已索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;record_manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SQLRecordManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;chroma/my_docs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;db_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sqlite:///record_manager.db&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;record_manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_schema&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 执行索引（自动去重、增量更新）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;record_manager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cleanup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;incremental&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 增量模式：新增的写入，删除的移除&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;source_id_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;source&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;新增: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;num_added&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 删除: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;num_deleted&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 更新: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;num_updated&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 跳过: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;num_skipped&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="一个完整-rag-链"&gt;一个完整 RAG 链
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.runnables&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 检索 + 生成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;请根据以下上下文回答问题。如果上下文中没有相关信息，请说&amp;#34;我不知道&amp;#34;。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;上下文：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&lt;/span&gt;&lt;span class="si"&gt;{context}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;问题：&lt;/span&gt;&lt;span class="si"&gt;{question}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;format_docs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 经典 RAG 链&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;rag_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;context&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;format_docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rag_chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LangChain 的 Memory 组件有什么作用？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="33-链chains"&gt;3.3 链（Chains）
&lt;/h3&gt;&lt;p&gt;链允许将多个组件组合在一起，创建单一的、连贯的应用程序。例如，创建一个链接受用户输入，使用提示模板格式化，然后传递给 LLM。&lt;/p&gt;
&lt;p&gt;LangChain 中主要链类型：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;链类型&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;基础链 LLMChain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;围绕语言模型添加功能，由 PromptTemplate 和 LLM/ChatModel 组成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;路由链 RouterChain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;动态选择下一条链，含 LLMRouterChain 和 EmbeddingRouterChain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;顺序链 SequentialChain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将多个链顺序连接，输出作为下一个链的输入；SimpleSequentialChain（单输入输出）和 SequentialChain（多输入输出）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;转换链 TransformChain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;在链之间添加自定义转换函数（清理、过滤、格式化数据）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;文档链 DocumentsChain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将多个文档作为输入传递给下游链，支持合并、抽取、路由&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 传统 LLMChain（已被 LCEL 替代，但理解原理有价值）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;讲一个关于&lt;/span&gt;&lt;span class="si"&gt;{subject}&lt;/span&gt;&lt;span class="s2"&gt;的笑话&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;subject&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;程序员&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 顺序链：第一步总结，第二步翻译&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SimpleSequentialChain&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;summary_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;用一句话总结：&lt;/span&gt;&lt;span class="si"&gt;{text}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;translate_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;把以下内容翻译成英文：&lt;/span&gt;&lt;span class="si"&gt;{text}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;overall_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SimpleSequentialChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chains&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;summary_chain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;translate_chain&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;overall_chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LangChain 是一个用于构建 LLM 应用的框架，提供六大核心组件...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;链支持序列化到磁盘或从磁盘加载，可子类化自定义实现特定 NLP 任务。但注意：&lt;strong&gt;新版 LangChain 推荐用 LCEL（第四章）替代传统 Chains&lt;/strong&gt;，传统 Chains 主要用于理解原理和维护旧代码。&lt;/p&gt;
&lt;h3 id="34-记忆memory"&gt;3.4 记忆（Memory）
&lt;/h3&gt;&lt;p&gt;Memory 组件用于在链之间存储和传递信息，实现对话的上下文感知能力。&lt;/p&gt;
&lt;p&gt;关键功能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;存储之前对话和验证信息的状态，用于后续链的输入&lt;/li&gt;
&lt;li&gt;允许链访问和操作共享的内存，实现链之间的协作&lt;/li&gt;
&lt;li&gt;支持不同的内存存储后端（字典、数据库等）&lt;/li&gt;
&lt;li&gt;可存储各种数据类型（文本、图像、音频等）&lt;/li&gt;
&lt;li&gt;实现对话系统的用户个性化、任务跟踪&lt;/li&gt;
&lt;li&gt;存储链的中间执行状态，实现断点恢复&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ConversationChain&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.memory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ConversationBufferMemory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 完整对话历史&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ConversationBufferWindowMemory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 只保留最近 N 轮&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ConversationTokenBufferMemory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 按 Token 数限制&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ConversationSummaryMemory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 摘要式记忆&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 完整缓冲区记忆（简单但会撑爆上下文）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConversationBufferMemory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 窗口记忆（只保留最近 5 轮，省 Token）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConversationBufferWindowMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. Token 限制记忆（按 Token 数截断）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConversationTokenBufferMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;max_token_limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. 摘要记忆（把历史对话压缩成摘要）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConversationSummaryMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conversation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConversationChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 多轮对话，记忆自动维护&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;我叫小明，今年 25 岁&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;我喜欢 Python 编程&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;我叫什么？多大了？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# 能回忆起前面说的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：在 LangGraph 时代，Memory 类的复杂状态管理能力已被 LangGraph 的 State + Checkpointer 机制取代（见第五章）。传统 Memory 主要用于简单的 Chain 场景。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3 id="35-代理agents"&gt;3.5 代理（Agents）
&lt;/h3&gt;&lt;p&gt;代理的核心思想是使用 LLM 作为大脑自动思考，自动决策选择执行不同的动作，最终完成目标任务。&lt;/p&gt;
&lt;h4 id="关键组件"&gt;关键组件
&lt;/h4&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;组件&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent（代理）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;通过 LLM 决定下一步执行什么动作，扮演决策角色&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tools（工具）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;代理调用的函数或 API，需被正确描述以便代理调用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Toolkits（工具集）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一组可供选择的工具集，让 LLM 有更多能力和选择&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AgentExecutor（代理执行器）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;处理代理选择工具时的异常，提供日志记录和可观察性&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="定义工具"&gt;定义工具
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;获取指定城市的天气信息。输入城市名称，返回天气描述。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 实际项目中这里调用真实天气 API&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;weather_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;北京&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;晴 25°C&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;上海&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;多云 28°C&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;广州&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;雷雨 30°C&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;weather_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;：暂无天气数据&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;计算数学表达式的结果。输入如 &amp;#39;2+3*4&amp;#39;，返回计算结果。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 生产环境请用安全的表达式解析器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;计算失败：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_wiki&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;搜索维基百科获取知识。输入搜索关键词。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;关于&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;的维基百科摘要：...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;search_wiki&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;工具描述（docstring）的质量直接决定 Agent 调用成功率。这和 Claude Code 的 Skill 机制有异曲同工之妙——后面会专门对比。&lt;/p&gt;
&lt;h4 id="最新演进create_agent"&gt;最新演进：create_agent
&lt;/h4&gt;&lt;p&gt;LangChain 最新版本提供 &lt;code&gt;create_agent&lt;/code&gt; 作为最小化、高度可配置的 Agent harness：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;openai:gpt-5.5&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;search_wiki&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;你是一个能查天气、算数学、搜百科的助手，回答要简洁&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;北京天气怎么样？2的10次方是多少？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Agent 会自主决定调用哪些工具、按什么顺序调用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;create_agent&lt;/code&gt; 的设计体现了 &amp;ldquo;Agent = Model + Harness&amp;rdquo; 理念：你提供模型、工具、提示词和中间件，框架负责把&amp;quot;模型循环&amp;quot;组织起来。支持多模型提供商：OpenAI、Google Gemini、Anthropic Claude、OpenRouter、Fireworks、Ollama、Azure、AWS Bedrock、HuggingFace 等。&lt;/p&gt;
&lt;h4 id="工具绑定"&gt;工具绑定
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# bind_tools 把工具信息注入模型，模型能&amp;#34;看到&amp;#34;工具并决定调用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm_with_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm_with_tools&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;北京天气怎么样？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;模型决定调用: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 参数: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;args&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="36-回调callbacks"&gt;3.6 回调（Callbacks）
&lt;/h3&gt;&lt;p&gt;LangChain 提供了一个回调系统，允许连接到 LLM 申请的各个阶段。这对于日志记录、监控、流传输和其他任务（添加标签、计算 Token 等）非常有用。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.callbacks&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseCallbackHandler&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyCallbackHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseCallbackHandler&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_llm_start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;serialized&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[LLM 开始] 模型: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;serialized&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_llm_new_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 流式输出时，每个 token 都会触发&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_llm_end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;[LLM 结束] 耗时统计完成&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_tool_start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;serialized&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[工具开始] &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;serialized&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input_str&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_tool_end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[工具结束] 返回: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_chain_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[链错误] &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 使用回调&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;streaming&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;callbacks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MyCallbackHandler&lt;/span&gt;&lt;span class="p"&gt;()])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;用三句话介绍量子计算&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;回调系统是 LangSmith 追踪的底层基础——LangSmith 本质上就是一套预配置的回调处理器，把每一步的输入输出、耗时、工具调用都记录下来。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;第三章实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;六大组件的协作链路：Model I/O 负责&amp;quot;说&amp;quot;，Data Connection 负责&amp;quot;找资料&amp;quot;，Chains 负责&amp;quot;串&amp;quot;，Memory 负责&amp;quot;记&amp;quot;，Agents 负责&amp;quot;想&amp;quot;，Callbacks 负责&amp;quot;观察&amp;quot;。&lt;/li&gt;
&lt;li&gt;工具描述（docstring）质量决定 Agent 成败，把&amp;quot;什么场景该调我、参数怎么传&amp;quot;写清楚。&lt;/li&gt;
&lt;li&gt;传统 Memory 在复杂场景已被 LangGraph State 取代，简单对话用 Memory 够了，复杂状态管理上 LangGraph。&lt;/li&gt;
&lt;li&gt;Callbacks 是可观测性的底层抓手，LangSmith 就是基于它实现的。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第四章-lcellangchain-expression-language"&gt;第四章 LCEL（LangChain Expression Language）
&lt;/h2&gt;&lt;h3 id="41-什么是-lcel"&gt;4.1 什么是 LCEL
&lt;/h3&gt;&lt;p&gt;LCEL（LangChain Expression Language）是 LangChain 框架中用于构建链式调用的表达式语言，通过&lt;strong&gt;管道符号 &lt;code&gt;|&lt;/code&gt;&lt;/strong&gt; 串联提示词模板、模型和输出解析器等组件。它以&amp;quot;管道&amp;quot;方式组合组件，是对传统 Chains 的现代化替代。&lt;/p&gt;
&lt;p&gt;如果你用过 Unix 管道 &lt;code&gt;cat file | grep &amp;quot;error&amp;quot; | wc -l&lt;/code&gt;，那么 LCEL 的心智模型完全一样：前一步的输出，自动成为后一步的输入。&lt;/p&gt;
&lt;h3 id="42-runnable统一接口"&gt;4.2 Runnable：统一接口
&lt;/h3&gt;&lt;p&gt;LCEL 的基石是 &lt;strong&gt;Runnable&lt;/strong&gt; 协议。所有 LCEL 组件（prompt、llm、parser、retriever，甚至自定义函数）都实现了 Runnable 接口，提供统一的方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Runnable 统一接口 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ invoke(input) 同步单次调用 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ainvoke(input) 异步单次调用 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ stream(input) 同步流式（逐块返回） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ astream(input) 异步流式 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ batch(inputs) 批量调用（并行处理多个输入） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ abatch(inputs) 异步批量 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├ | 管道组合：chain = prompt | llm | parser │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └ ~ 也能用 RunnablePassthrough 透传原输入 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这意味着：不管你组合多少个组件，最终得到的 &lt;code&gt;chain&lt;/code&gt; 对象都有 &lt;code&gt;invoke/stream/batch&lt;/code&gt; 方法。你不需要为流式单独写一套代码，也不需要为异步单独写一套——LCEL 在底层帮你处理了。&lt;/p&gt;
&lt;h3 id="43-lcel-核心优势"&gt;4.3 LCEL 核心优势
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;简化流式输出（Simplify streaming）&lt;/strong&gt;：LCEL 链可以被流式处理，允许在链执行时增量输出。LangChain 可以优化输出流式，最小化首 Token 时间（time-to-first-token）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异步支持&lt;/strong&gt;：LCEL 链天然支持异步执行，适用于高并发场景。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;批量处理&lt;/strong&gt;：支持批量处理多个输入。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并行执行&lt;/strong&gt;：使用 &lt;code&gt;RunnableParallel&lt;/code&gt; 等组件实现并行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;回退机制&lt;/strong&gt;：支持 fallback，当主流程失败时自动切换备用方案。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;统一接口&lt;/strong&gt;：所有 Runnable 组件遵循统一接口（invoke/ainvoke/stream/astream/batch）。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="44-基本用法"&gt;4.4 基本用法
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 用管道符 | 串联组件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;请解释什么是 &lt;/span&gt;&lt;span class="si"&gt;{topic}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 统一接口调用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LCEL&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 流式调用（Token 级输出）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LCEL&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 批量调用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;([{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;RAG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;topic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Memory&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="45-runnableparallel-并行执行"&gt;4.5 RunnableParallel 并行执行
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.runnables&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunnableParallel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;summary_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;总结：&lt;/span&gt;&lt;span class="si"&gt;{input}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;keyword_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;提取3个关键词：&lt;/span&gt;&lt;span class="si"&gt;{input}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sentiment_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;判断情感(正面/负面/中性)：&lt;/span&gt;&lt;span class="si"&gt;{input}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 三条链并行执行，共享同一个输入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;parallel_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RunnableParallel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;summary_prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;keyword_prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sentiment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sentiment_prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# RunnablePassthrough 透传原始输入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parallel_chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LangChain 是一个强大的 LLM 应用开发框架，社区活跃但学习曲线较陡。&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;summary&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;keywords&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sentiment&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;并行执行在多维度分析场景非常有用：同一段文本同时做摘要、关键词提取、情感分析，一次调用出三个结果。&lt;/p&gt;
&lt;h3 id="46-runnablepassthrough-透传"&gt;4.6 RunnablePassthrough 透传
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 经典 RAG 模式：检索结果 + 原始问题一起喂给模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;rag_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;format_docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# RunnablePassthrough.assign() 在不丢失原始输入的基础上，追加 context 字段&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="47-回退机制fallbacks"&gt;4.7 回退机制（Fallbacks）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.runnables&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunnableWithFallbacks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 主模型失败时，自动切到备用模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;primary_llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 可能限流&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;fallback_llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-3.5-turbo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 更便宜更稳定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm_with_fallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;primary_llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with_fallbacks&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;fallback_llm&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm_with_fallback&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 如果 gpt-4 限流报错，自动用 gpt-3.5-turbo 重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="48-自定义-runnable"&gt;4.8 自定义 Runnable
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.runnables&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunnableLambda&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 任何函数都能用 RunnableLambda 包装成 Runnable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_user_intent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;简单意图识别&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;?&amp;#34;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;？&amp;#34;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;intent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;intent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;statement&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;intent_runnable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RunnableLambda&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extract_user_intent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 然后就能用管道符串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;intent_runnable&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="49-lcel-vs-传统-chains"&gt;4.9 LCEL vs 传统 Chains
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;传统 Chains&lt;/th&gt;
&lt;th&gt;LCEL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;组合方式&lt;/td&gt;
&lt;td&gt;类继承、预定义链&lt;/td&gt;
&lt;td&gt;管道符 &lt;code&gt;|&lt;/code&gt; 表达式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;流式输出&lt;/td&gt;
&lt;td&gt;需额外配置&lt;/td&gt;
&lt;td&gt;天然支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;异步&lt;/td&gt;
&lt;td&gt;需手动实现&lt;/td&gt;
&lt;td&gt;自动支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;并行&lt;/td&gt;
&lt;td&gt;复杂&lt;/td&gt;
&lt;td&gt;RunnableParallel 简洁&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可读性&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;高（声明式）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;灵活性&lt;/td&gt;
&lt;td&gt;受限于预定义结构&lt;/td&gt;
&lt;td&gt;完全自由组合&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;回退&lt;/td&gt;
&lt;td&gt;需手写 try/except&lt;/td&gt;
&lt;td&gt;with_fallbacks 一行搞定&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="同一个需求两种写法对比"&gt;同一个需求，两种写法对比
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# === 传统 Chains 写法 ===&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain_old&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;翻译成英文：&lt;/span&gt;&lt;span class="si"&gt;{text}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain_old&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;你好世界&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# === LCEL 写法 ===&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain_new&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;翻译成英文：&lt;/span&gt;&lt;span class="si"&gt;{text}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain_new&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;你好世界&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 更短、更声明式、还免费获得了 stream/batch/async 能力&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="410-lcel-的数据流图"&gt;4.10 LCEL 的数据流图
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; invoke({&amp;#34;topic&amp;#34;: &amp;#34;RAG&amp;#34;})
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ChatPromptTemplate │ 渲染模板
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ {topic} → &amp;#34;请解释RAG&amp;#34; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └────────────┬────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ messages
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ChatOpenAI │ 调用模型
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ → AIMessage(&amp;#34;RAG是…&amp;#34;) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └────────────┬────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ AIMessage
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ StrOutputParser │ 解析输出
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ → &amp;#34;RAG是检索增强生成&amp;#34; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └────────────┬────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ str
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 最终结果
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; stream() 时：每个 | 之间的输出都逐块传递，实现真正的流式
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; batch() 时：多个输入并行走完整条链
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;第四章实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LCEL 是新代码的首选，传统 Chains 只用于维护旧代码。&lt;/li&gt;
&lt;li&gt;掌握 Runnable 统一接口（invoke/stream/batch/ainvoke），所有组件都能用同一套方法。&lt;/li&gt;
&lt;li&gt;RunnableParallel 做并行分析，RunnablePassthrough 做输入透传，with_fallbacks 做容错——这三个是 LCEL 的高频武器。&lt;/li&gt;
&lt;li&gt;流式是&amp;quot;免费&amp;quot;的：只要你的链是 LCEL 组合的，&lt;code&gt;chain.stream()&lt;/code&gt; 就能逐 Token 输出。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第五章-langgraph-多-agent-编排"&gt;第五章 LangGraph 多 Agent 编排
&lt;/h2&gt;&lt;h3 id="51-什么是-langgraph"&gt;5.1 什么是 LangGraph
&lt;/h3&gt;&lt;p&gt;LangGraph 是一个用于构建&lt;strong&gt;有状态、多步骤 AI 应用和自主智能体&lt;/strong&gt;的低级编排框架。它将 Agent 工作流建模为&lt;strong&gt;有向图&lt;/strong&gt;，通过节点（Nodes）和边（Edges）的组合，实现对复杂 AI 工作流的精确控制。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心定位&lt;/strong&gt;：LangGraph 专注于 Agent 编排（Orchestration），提供持久化执行、流式输出、人工干预等底层基础设施。&lt;/p&gt;
&lt;p&gt;如果用一句话区分 LangChain 和 LangGraph：&lt;strong&gt;LangChain 提供积木，LangGraph 提供脚手架&lt;/strong&gt;。积木让你能组合组件，脚手架让你能精确控制组件之间的执行流程、状态流转和容错恢复。&lt;/p&gt;
&lt;h3 id="52-为什么需要-langgraph"&gt;5.2 为什么需要 LangGraph
&lt;/h3&gt;&lt;p&gt;传统 Agent 框架（如 LangChain 的 ReAct Agent）存在以下局限：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;问题&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;LangGraph 解决方案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;流程不可控&lt;/td&gt;
&lt;td&gt;Agent 自主循环，难以精确控制&lt;/td&gt;
&lt;td&gt;图结构定义流程，条件路由精确控制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;状态管理弱&lt;/td&gt;
&lt;td&gt;依赖 Memory 类，难以管理复杂状态&lt;/td&gt;
&lt;td&gt;内置 State 机制，支持 Reducer 聚合&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;无持久化&lt;/td&gt;
&lt;td&gt;进程崩溃后状态丢失&lt;/td&gt;
&lt;td&gt;Checkpoint 持久化，断点恢复&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;无法人工干预&lt;/td&gt;
&lt;td&gt;Agent 全自动，关键决策无法暂停&lt;/td&gt;
&lt;td&gt;interrupt() 动态中断 + Human-in-the-loop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;循环工作流难&lt;/td&gt;
&lt;td&gt;依赖递归或 while 循环&lt;/td&gt;
&lt;td&gt;图天然支持循环（边可指回已访问节点）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="53-langgraph-架构全景"&gt;5.3 LangGraph 架构全景
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LangGraph 架构全景 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ State │◀───│ Nodes │───▶│ Edges │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ (状态) │ │ (节点) │ │ (边) │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─────────┘ └──────────┘ └─────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Reducer │ 条件路由 │ 普通边/循环边 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ (聚合策略) │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ▼ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌─────────────────────────────────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ StateGraph (有向图) │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ compile() → 可执行图 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └────────────────────┬────────────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌─────────────┼─────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ▼ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │Checkpoint│ │Interrupt │ │ Streaming│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │(持久化) │ │(人工干预)│ │ (流式) │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └──────────┘ └──────────┘ └──────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 多 Agent 模式：Supervisor / Network / Reflection │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="54-核心概念"&gt;5.4 核心概念
&lt;/h3&gt;&lt;h4 id="541-状态state"&gt;5.4.1 状态（State）
&lt;/h4&gt;&lt;p&gt;State 是图的核心数据结构，表示应用在任意时刻的快照。所有节点读取和更新同一个 State。&lt;/p&gt;
&lt;p&gt;定义方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TypedDict&lt;/strong&gt;（最常用）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dataclass&lt;/strong&gt;（支持默认值）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pydantic BaseModel&lt;/strong&gt;（数据验证）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Reducer 机制&lt;/strong&gt;决定节点返回的更新如何应用到 State——这是 LangGraph 区别于普通函数调用的关键：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Reducer 类型&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;默认（无 Reducer）&lt;/td&gt;
&lt;td&gt;新值直接覆盖旧值&lt;/td&gt;
&lt;td&gt;&lt;code&gt;current_step: str&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operator.add&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;列表累加&lt;/td&gt;
&lt;td&gt;&lt;code&gt;messages: Annotated[list, add]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;自定义 Reducer&lt;/td&gt;
&lt;td&gt;自定义合并逻辑&lt;/td&gt;
&lt;td&gt;传入任意函数&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;operator&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 累加模式：新消息追加到列表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;current_step&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="c1"&gt;# 覆盖模式：新值替换旧值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 累加模式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;为什么需要 Reducer？因为多个节点可能同时更新同一个字段。比如 &lt;code&gt;messages&lt;/code&gt;，每个节点都会产生新消息，你希望它们&lt;strong&gt;累加&lt;/strong&gt;而不是&lt;strong&gt;覆盖&lt;/strong&gt;。如果没有 Reducer，后一个节点的返回会直接覆盖前一个，导致历史消息丢失。这是新手最常踩的坑之一。&lt;/p&gt;
&lt;h4 id="542-节点nodes"&gt;5.4.2 节点（Nodes）
&lt;/h4&gt;&lt;p&gt;节点是图中的计算单元，封装 Agent 的逻辑。每个节点是一个函数，接收当前 State，执行计算，返回 State 更新。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心原则：节点做工作，边决定下一步。&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.messages&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AIMessage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;analyze_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;分析用户输入，确定意图&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user_msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;intent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;search&amp;#34;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;查&amp;#34;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;user_msg&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;chat&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;current_step&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# 只返回要更新的字段&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;llm_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;使用 LLM 生成回复&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="c1"&gt;# Reducer 会自动累加到 messages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;执行检索&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;根据以下资料回答：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;问题：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;results&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="543-边edges"&gt;5.4.3 边（Edges）
&lt;/h4&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;边类型&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;普通边&lt;/td&gt;
&lt;td&gt;固定从一个节点到另一个节点&lt;/td&gt;
&lt;td&gt;A → B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;条件边&lt;/td&gt;
&lt;td&gt;根据条件路由到不同节点&lt;/td&gt;
&lt;td&gt;A → B or C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;START 边&lt;/td&gt;
&lt;td&gt;图的入口&lt;/td&gt;
&lt;td&gt;START → A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;END 边&lt;/td&gt;
&lt;td&gt;图的出口&lt;/td&gt;
&lt;td&gt;A → END&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;条件边是 LangGraph 的核心能力：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;route_by_intent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;根据意图路由到不同节点&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;current_step&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;search&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;search_node&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;llm_node&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;analyze&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;analyze_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;search_node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;search_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;llm_node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;llm_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;analyze&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;analyze&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;route_by_intent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;search_node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;search_node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;llm_node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;llm_node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;search_node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;llm_node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="544-编译与执行"&gt;5.4.4 编译与执行
&lt;/h4&gt;&lt;p&gt;图必须编译后才能使用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 基础编译&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 带 Checkpointer 编译（启用持久化）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.checkpoint.memory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;InMemorySaver&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;InMemorySaver&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 带断点编译（在指定节点前暂停）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interrupt_before&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;approval_node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;执行方法：&lt;code&gt;invoke&lt;/code&gt;（同步）、&lt;code&gt;stream&lt;/code&gt;（流式）、&lt;code&gt;ainvoke&lt;/code&gt;（异步）、&lt;code&gt;astream&lt;/code&gt;（异步流式）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;configurable&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;thread_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user-123&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;帮我查一下 LangChain 是什么&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)]},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="545-完整图结构示例"&gt;5.4.5 完整图结构示例
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ START │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └────┬────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ analyze │ 分析意图
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──────┬──────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 条件路由 route_by_intent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌────┴────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼ ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌──────────┐ ┌──────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │search_node│ │ llm_node │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────┬────┘ └────┬─────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────┬──────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ END │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="55-持久化与记忆"&gt;5.5 持久化与记忆
&lt;/h3&gt;&lt;h4 id="checkpointer-选型"&gt;Checkpointer 选型
&lt;/h4&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Checkpointer&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;th&gt;持久化&lt;/th&gt;
&lt;th&gt;性能&lt;/th&gt;
&lt;th&gt;并发支持&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;InMemorySaver&lt;/td&gt;
&lt;td&gt;开发调试&lt;/td&gt;
&lt;td&gt;否（进程内）&lt;/td&gt;
&lt;td&gt;最快&lt;/td&gt;
&lt;td&gt;单进程&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SqliteSaver&lt;/td&gt;
&lt;td&gt;本地/单机&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;单进程&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PostgresSaver&lt;/td&gt;
&lt;td&gt;生产环境&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;多进程&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="两种记忆类型"&gt;两种记忆类型
&lt;/h4&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;记忆类型&lt;/th&gt;
&lt;th&gt;实现方式&lt;/th&gt;
&lt;th&gt;作用域&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;短期记忆&lt;/td&gt;
&lt;td&gt;Checkpointer&lt;/td&gt;
&lt;td&gt;单线程（Thread）&lt;/td&gt;
&lt;td&gt;对话上下文&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;长期记忆&lt;/td&gt;
&lt;td&gt;BaseStore&lt;/td&gt;
&lt;td&gt;跨线程（全局）&lt;/td&gt;
&lt;td&gt;用户偏好、知识积累&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.checkpoint.postgres&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PostgresSaver&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.store.memory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;InMemoryStore&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 生产级持久化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PostgresSaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_conn_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;postgresql://...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 长期记忆存储（跨对话线程）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;InMemoryStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 生产用 PostgresStore&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 记住用户偏好&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;123&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;preferences&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;language&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;zh&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;formal&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;短期记忆（Checkpointer）让对话能在崩溃后恢复、能跨请求延续上下文；长期记忆（Store）让不同对话线程之间共享用户画像和知识积累。这是 Memory 类做不到的——Memory 只能在一个 Chain 实例内保持上下文。&lt;/p&gt;
&lt;h3 id="56-人工干预human-in-the-loop"&gt;5.6 人工干预（Human-in-the-Loop）
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;interrupt()&lt;/code&gt; 是 LangGraph 的核心人工干预机制，可在节点内任意位置暂停执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.types&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;interrupt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;approval_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 暂停执行，等待人工审核&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;approved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;interrupt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;请确认是否执行此操作？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;approved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;approved&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;操作已执行&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;approved&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;操作已取消&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 第一次调用：遇到 interrupt 暂停&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;configurable&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;thread_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;approval-1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;删除数据库&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)]},&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 此时执行暂停在 approval_node，等待人工输入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 恢复执行：传入人工审核结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resume&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;人工干预的典型场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;危险操作审核&lt;/strong&gt;：删除、支付、发邮件等不可逆操作前暂停&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键决策确认&lt;/strong&gt;：模型选了方案 A，让人确认是否采纳&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内容审核&lt;/strong&gt;：生成的内容发布前让人过目&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="57-流式输出"&gt;5.7 流式输出
&lt;/h3&gt;&lt;p&gt;LangGraph 提供多种流模式，满足不同场景需求：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;values&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;每步之后的完整 State&lt;/td&gt;
&lt;td&gt;调试全貌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;updates&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;每步之后的 State 增量更新&lt;/td&gt;
&lt;td&gt;调试状态变化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;messages&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;LLM Token 级别流式输出&lt;/td&gt;
&lt;td&gt;用户交互（打字机效果）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;custom&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;节点自定义流式数据&lt;/td&gt;
&lt;td&gt;进度条、中间结果&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;checkpoints&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查点事件&lt;/td&gt;
&lt;td&gt;持久化监控&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tasks&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;任务开始/完成事件&lt;/td&gt;
&lt;td&gt;任务调度监控&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Token 级流式（用户看到打字机效果）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;讲个故事&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)]},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stream_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# event 是 (message, metadata) 元组&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 状态增量流式（调试用）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;查 LangChain&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)]},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stream_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;updates&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;node_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[节点 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;node_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] 更新: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="58-多-agent-架构模式"&gt;5.8 多 Agent 架构模式
&lt;/h3&gt;&lt;h4 id="模式一supervisor-模式主管模式"&gt;模式一：Supervisor 模式（主管模式）
&lt;/h4&gt;&lt;p&gt;一个主管 Agent 负责任务调度，将任务分配给不同的专家 Agent：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;supervisor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;主管 Agent：决定将任务分配给哪个专家&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SystemMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;你是一个任务调度器。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 可选专家：researcher(查资料)、writer(写文章)、reviewer(审稿)。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 只返回专家名字。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;next_agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;researcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;研究员 Agent&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AIMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;研究完成：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;写作 Agent&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reviewer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;审稿 Agent&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SystemMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;你是审稿人，给出修改建议&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 构建图&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;supervisor&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;supervisor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;researcher&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;researcher&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;writer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;reviewer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reviewer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;supervisor&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;supervisor&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;next_agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;researcher&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;researcher&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;writer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;writer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;reviewer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;reviewer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;FINISH&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 每个专家做完回到主管&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;researcher&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;supervisor&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;writer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;supervisor&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;reviewer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;supervisor&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Supervisor 模式结构图：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ Supervisor │◀─────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────┬──────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 条件路由 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌────────┬───┴────┐────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼ ▼ ▼ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────┐┌──────┐┌──────┐┌──────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│researcher│writer│reviewer│ FINISH │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──┬───┘└──┬───┘└──┬───┘└──────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └────────┴───────┴──────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; （每个专家做完回到主管，由主管决定下一步）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="模式二network-模式多-agent-协作"&gt;模式二：Network 模式（多 Agent 协作）
&lt;/h4&gt;&lt;p&gt;多个 Agent 并行执行，由综合器合并结果：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;researcher_a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 并行执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;researcher_b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 并行执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;researcher_a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;synthesizer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;researcher_b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;synthesizer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;synthesizer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ START │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──┬───┬──┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌────┘ └────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼ ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────┐ ┌──────────┐ 并行
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│researcher│ │researcher│ 执行
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ _a │ │ _b │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└────┬─────┘ └────┬─────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └────┬───┬───┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼ ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌──────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │synthesizer│ 合并结果
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────┬────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ END │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="模式三反思与自我改进-agent"&gt;模式三：反思与自我改进 Agent
&lt;/h4&gt;&lt;p&gt;通过&amp;quot;生成→批评→修改→再批评&amp;quot;的循环实现自我改进：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;should_continue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;iteration_count&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;finalize&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;critique_approved&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;finalize&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;revise&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;generate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;generate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;critique&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;critique&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;should_continue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;revise&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;revise&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;finalize&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;finalize&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;revise&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;critique&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 循环&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;finalize&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; START → generate → critique ──┬── revise ──┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▲ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──────────┘ (循环) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; should_continue │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌──────────┴──────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; revise finalize → END
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="59-langgraph-vs-其他编排框架"&gt;5.9 LangGraph vs 其他编排框架
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;LangGraph&lt;/th&gt;
&lt;th&gt;Temporal + AI&lt;/th&gt;
&lt;th&gt;CrewAI&lt;/th&gt;
&lt;th&gt;AutoGen&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;编排方式&lt;/td&gt;
&lt;td&gt;有向图&lt;/td&gt;
&lt;td&gt;工作流引擎&lt;/td&gt;
&lt;td&gt;角色协作&lt;/td&gt;
&lt;td&gt;对话驱动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;状态管理&lt;/td&gt;
&lt;td&gt;内置 State + Checkpoint&lt;/td&gt;
&lt;td&gt;外部持久化&lt;/td&gt;
&lt;td&gt;有限&lt;/td&gt;
&lt;td&gt;有限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;人工干预&lt;/td&gt;
&lt;td&gt;原生支持&lt;/td&gt;
&lt;td&gt;支持&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;td&gt;部分&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;灵活性&lt;/td&gt;
&lt;td&gt;极高（低级 API）&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;学习曲线&lt;/td&gt;
&lt;td&gt;较陡&lt;/td&gt;
&lt;td&gt;陡&lt;/td&gt;
&lt;td&gt;平缓&lt;/td&gt;
&lt;td&gt;平缓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLM 集成&lt;/td&gt;
&lt;td&gt;LangChain 生态&lt;/td&gt;
&lt;td&gt;需自建&lt;/td&gt;
&lt;td&gt;内置&lt;/td&gt;
&lt;td&gt;内置&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="510-仿-dify-工作流系统"&gt;5.10 仿 Dify 工作流系统
&lt;/h3&gt;&lt;p&gt;LangGraph 可以实现类 Dify 的可视化工作流引擎，核心是&amp;quot;DSL 驱动 + 动态图构建&amp;quot;架构：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dify 节点类型&lt;/th&gt;
&lt;th&gt;LangGraph 实现方式&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;start&lt;/td&gt;
&lt;td&gt;图的输入 State&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;llm&lt;/td&gt;
&lt;td&gt;LLM 节点函数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;knowledge-retrieval&lt;/td&gt;
&lt;td&gt;LangChain VectorStore 节点&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;code&lt;/td&gt;
&lt;td&gt;exec() 沙箱节点&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;http-request&lt;/td&gt;
&lt;td&gt;requests/httpx 节点&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;if-else&lt;/td&gt;
&lt;td&gt;条件边 add_conditional_edges()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;human-review&lt;/td&gt;
&lt;td&gt;interrupt() + Command(resume=&amp;hellip;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;loop/iteration&lt;/td&gt;
&lt;td&gt;循环边 + 计数器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;answer&lt;/td&gt;
&lt;td&gt;END 节点&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 用 YAML DSL 定义工作流，动态解析为 LangGraph 图&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;yaml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;workflow_yaml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;nodes:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - id: start
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; type: input
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - id: retrieve
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; type: knowledge-retrieval
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; config:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; vectorstore: chroma
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; k: 3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - id: generate
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; type: llm
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; config:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; model: gpt-4
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; prompt_template: &amp;#34;根据资料回答：&lt;/span&gt;&lt;span class="si"&gt;{context}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n问题：&lt;/span&gt;&lt;span class="si"&gt;{question}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - id: review
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; type: human-review
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - id: answer
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; type: output
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;edges:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - {from: start, to: retrieve}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - {from: retrieve, to: generate}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - {from: generate, to: review}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - {from: review, to: answer}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 动态构建图（伪代码，展示思路）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_graph_from_dsl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dsl&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;spec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;safe_load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dsl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;nodes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;create_node_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;edge&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;edges&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edge&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;from&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;edge&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;to&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PostgresSaver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_graph_from_dsl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workflow_yaml&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;通过 YAML DSL 定义工作流配置，动态解析为 LangGraph 图，实现可视化工作流编排。这种架构让你能把工作流配置和代码解耦——产品经理在界面上拖拽节点生成 YAML，后端解析成图执行。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;第五章实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LangGraph 的心智模型：节点做工作，边决定下一步。把流程画成图，问题就清晰了。&lt;/li&gt;
&lt;li&gt;Reducer 是最常踩的坑：并行节点更新同一字段必须用累加 Reducer，否则后写覆盖前写。&lt;/li&gt;
&lt;li&gt;生产环境必用 PostgresSaver，InMemorySaver 只用于开发调试。&lt;/li&gt;
&lt;li&gt;interrupt() + Command(resume=&amp;hellip;) 是人工干预的标准范式，危险操作前必须暂停。&lt;/li&gt;
&lt;li&gt;仿 Dify 的 DSL 驱动架构能让工作流可配置化，适合需要频繁调整流程的场景。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第六章-langsmith-调试与监控"&gt;第六章 LangSmith 调试与监控
&lt;/h2&gt;&lt;h3 id="61-什么是-langsmith"&gt;6.1 什么是 LangSmith
&lt;/h3&gt;&lt;p&gt;LangSmith 是 LangChain 生态系统的&lt;strong&gt;可观测性平台&lt;/strong&gt;，提供 Agent 和 LLM 应用的完整可观测性。一个关键特性是：它&lt;strong&gt;框架无关&lt;/strong&gt;——支持追踪首选框架，或通过 Python、TypeScript、Go、Java SDK 集成任何 Agent 技术栈。即使你不用 LangChain，只用原生 OpenAI SDK 手搓 Agent，LangSmith 依然能帮你追踪。&lt;/p&gt;
&lt;h3 id="62-为什么需要-langsmith"&gt;6.2 为什么需要 LangSmith
&lt;/h3&gt;&lt;p&gt;Agent 应用的调试难度远超传统软件。一个 Agent 可能跑了十步：调了 3 次模型、2 次工具、1 次检索，最后输出一个错误答案。到底哪一步出了问题？没有追踪，你只能靠猜。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;没有 LangSmith： 有 LangSmith：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌────────────────────┐ ┌────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 用户提问 │ │ 用户提问 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ↓ │ │ ↓ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ??? 黑盒 ??? │ │ Step1: analyze (0.2s) ✓ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ↓ │ │ Step2: search (1.3s) ✓ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 错误答案 │ │ Step3: llm (2.1s) ✗ 格式错误│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ ↓ 原因：提示词缺格式约束 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 只能瞎猜哪错了 │ │ 错误答案 → 精确定位到 Step3 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└────────────────────┘ └────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="63-核心能力"&gt;6.3 核心能力
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;能力&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;追踪（Tracing）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;检查追踪、工具调用、状态转换和延迟&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;调试（Debugging）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;定位失败模式，查找问题根因&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;评估（Evaluation）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;评估输出质量，改进 Agent 行为&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;监控（Monitoring）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LangSmith Engine 监控追踪、检测问题、提出修复建议&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;部署（Deployment）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;支持 AI Agent 应用的 CI/CD 管道&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据集管理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;跟踪数据样本或上传自定义数据集&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="64-快速上手"&gt;6.4 快速上手
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 设置追踪环境变量（只需设置一次，全局生效）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LANGSMITH_TRACING&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LANGSMITH_API_KEY&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;your-langsmith-key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LANGSMITH_PROJECT&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;langchain-project&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 设置后，所有 LangChain/LangGraph 的调用都会自动被追踪&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 不需要改任何业务代码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;什么是 RAG？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ↑ 这次调用会自动出现在 LangSmith 平台，含完整输入输出和耗时&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;设置后，所有 LangChain/LangGraph 的调用都会自动被追踪，可在 LangSmith 平台查看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每个步骤的模型输入输出&lt;/li&gt;
&lt;li&gt;调用性能问题定位&lt;/li&gt;
&lt;li&gt;工具调用详情&lt;/li&gt;
&lt;li&gt;状态转换过程&lt;/li&gt;
&lt;li&gt;延迟分析&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="65-追踪一个完整-agent"&gt;6.5 追踪一个完整 Agent
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 定义 Agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;搜索数据库&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;查询结果：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 的数据&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;openai:gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;search_db&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;你是一个数据查询助手&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 执行（自动追踪）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;查一下上月销售额&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 在 LangSmith 平台你会看到这样的追踪树：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Agent Run (total: 3.2s)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ├── Step 1: LLM 决策 (1.1s)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# │ └── 输出：调用 search_db(&amp;#34;上月销售额&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ├── Step 2: 工具执行 search_db (0.3s)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# │ └── 返回：&amp;#34;查询结果：上月销售额的数据&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ├── Step 3: LLM 总结 (1.5s)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# │ └── 输出：&amp;#34;上月销售额为...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# └── Step 4: 返回最终回复 (0.3s)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="66-评估与数据集"&gt;6.6 评估与数据集
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langsmith&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langsmith.evaluation&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;evaluate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 创建数据集&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;rag-eval-v1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 添加测试用例&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_examples&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LangChain 的核心组件有哪些？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;什么是 LCEL？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LangGraph 和 LangChain 的区别？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;answer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Model I/O, Data Connection, Chains, Memory, Agents, Callbacks&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;answer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LangChain Expression Language，用管道符组合组件&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;answer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LangChain 提供积木，LangGraph 提供图编排脚手架&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dataset_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 评估你的 RAG 链&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;accuracy_evaluator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;自定义评估器：检查答案是否包含关键信息&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prediction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;output&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;answer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kw&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;prediction&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;kw&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;accuracy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;score&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rag_chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;rag-eval-v1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;evaluators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;accuracy_evaluator&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;准确率: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;aggregate_metrics&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;accuracy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;.1%&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="67-langsmith-engine"&gt;6.7 LangSmith Engine
&lt;/h3&gt;&lt;p&gt;LangSmith Engine 会自动监控你的追踪，检测问题，并提出修复建议。它不仅能发现问题，还能主动帮助改进 Agent 行为。例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;检测到某个工具调用频繁失败 → 建议检查工具描述&lt;/li&gt;
&lt;li&gt;检测到某步耗时异常高 → 标记为性能瓶颈&lt;/li&gt;
&lt;li&gt;检测到输出格式不稳定 → 建议加强输出解析器&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="68-langsmith-与-callbacks-的关系"&gt;6.8 LangSmith 与 Callbacks 的关系
&lt;/h3&gt;&lt;p&gt;LangSmith 的追踪底层就是基于 Callbacks 实现的。当你设置 &lt;code&gt;LANGSMITH_TRACING=true&lt;/code&gt;，LangSmith 会自动注册一套回调处理器，拦截 LLM 调用、工具调用、链执行的每一个事件，上报到 LangSmith 平台。所以第四章讲的 Callbacks 是&amp;quot;手动版&amp;quot;的可观测性，LangSmith 是&amp;quot;自动版 + 平台化&amp;quot;的可观测性。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;第六章实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LangSmith 是横切所有层的，不管你用 LangChain、LangGraph 还是手搓，都建议挂上。&lt;/li&gt;
&lt;li&gt;只需设置环境变量就能自动追踪，零代码侵入，没理由不用。&lt;/li&gt;
&lt;li&gt;评估要建数据集做回归测试，Agent 改了提示词后跑一遍评估集，量化质量变化。&lt;/li&gt;
&lt;li&gt;LangSmith Engine 的自动问题检测能帮你发现&amp;quot;人肉看不过来&amp;quot;的异常模式。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第七章-langserve--langdeployment"&gt;第七章 LangServe / LangDeployment
&lt;/h2&gt;&lt;h3 id="71-langserve-现状"&gt;7.1 LangServe 现状
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;重要提示&lt;/strong&gt;：LangServe 已于 &lt;strong&gt;2024 年 11 月 18 日正式弃用&lt;/strong&gt;。官方推荐新项目使用 &lt;strong&gt;LangSmith Deployment&lt;/strong&gt;（原 LangGraph Platform，2025 年 10 月更名）作为 Agent 部署方案。&lt;/p&gt;
&lt;h3 id="72-为什么-langserve-被弃用"&gt;7.2 为什么 LangServe 被弃用
&lt;/h3&gt;&lt;p&gt;LangServe 当初的设计是把 Chain 封装成 FastAPI 服务，简单直接。但随着 Agent 应用变复杂，出现了 LangServe 难以处理的需求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;有状态工作流&lt;/strong&gt;：LangGraph 的 Checkpointer 需要跨请求恢复状态，LangServe 的无状态 API 模型不匹配&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;流式输出&lt;/strong&gt;：LangGraph 的多种 stream_mode 需要更复杂的流式协议&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人工干预&lt;/strong&gt;：interrupt/resume 需要请求挂起和恢复机制，简单 REST API 做不到&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;持久化&lt;/strong&gt;：生产级 Agent 需要数据库持久化，LangServe 不内置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;于是官方推出了 LangGraph Platform（后更名 LangDeployment），专门为有状态 Agent 设计。&lt;/p&gt;
&lt;h3 id="73-langdeployment新部署方案"&gt;7.3 LangDeployment（新部署方案）
&lt;/h3&gt;&lt;p&gt;LangDeployment（原 LangGraph Platform）是官方推荐的部署方案，将 Chain/Graph 封装为稳定 API 服务。&lt;/p&gt;
&lt;h4 id="部署能力"&gt;部署能力
&lt;/h4&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;能力&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;将 LangGraph 应用部署为 REST API 服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Studio&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可视化调试和监控界面&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cloud&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;云端托管部署&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;自托管&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;支持私有化部署&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="74-部署一个-langgraph-应用"&gt;7.4 部署一个 LangGraph 应用
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# langgraph.json - 部署配置文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;dependencies&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;graphs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;my_agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./app/agent.py:graph&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;env&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;.env&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# app/agent.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.checkpoint.postgres&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PostgresSaver&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ... 定义 State、Nodes、Edges（同第五章）...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ... add_node / add_edge ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 编译成可部署的图&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PostgresSaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_conn_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;DATABASE_URL&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;部署命令：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 安装 LangGraph CLI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install langgraph-cli
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 本地开发运行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;langgraph dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 构建部署镜像&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;langgraph build -t my-agent:latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 部署到 LangGraph Cloud&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;langgraph deploy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="75-调用部署后的-api"&gt;7.5 调用部署后的 API
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 同步调用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;http://localhost:8000/threads/my-agent/runs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;assistant_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;my_agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;你好&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}]},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;config&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;configurable&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;thread_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;session-1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 流式调用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sseclient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;http://localhost:8000/threads/my-agent/runs/stream&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;assistant_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;my_agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;讲个故事&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}]},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;stream_mode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sseclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SSEClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="76-langdeployment-部署架构"&gt;7.6 LangDeployment 部署架构
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LangDeployment 部署架构 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Client │───▶│ API Server │───▶│ LangGraph │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ (前端/SDK)│ │ (REST+SSE) │ │ App (图) │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └──────────┘ └──────┬───────┘ └──────┬───────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ ┌────────┴────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ ▼ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌──────┴───────┐ ┌──────────┐ ┌────────┐│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Studio │ │PostgreSQL│ │ LLM ││
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ (可视化调试) │ │(持久化) │ │ Provider││
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └──────────────┘ └──────────┘ └────────┘│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 横切：LangSmith 追踪贯穿所有层 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="77-部署选型建议"&gt;7.7 部署选型建议
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;简单 Demo / 轻量 RAG&lt;/strong&gt;：只用 LangChain + LangSmith 做调试，无需 LangGraph，直接用 FastAPI 包一层即可&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生产级 Agent&lt;/strong&gt;：使用 LangDeployment 将 Chain/Graph 封装为稳定 API 服务&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CD 管道&lt;/strong&gt;：LangSmith 部署 API 支持全面的 CI/CD 管道&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;第七章实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LangServe 已弃用，新项目直接上 LangDeployment。&lt;/li&gt;
&lt;li&gt;生产级 Agent 必须用 LangDeployment + PostgresSaver，别用 InMemorySaver 上生产。&lt;/li&gt;
&lt;li&gt;Studio 可视化调试是部署阶段的神器，能看到图的实时执行过程。&lt;/li&gt;
&lt;li&gt;简单场景不必上 LangDeployment，FastAPI 包一层 LCEL 链就够了。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第八章-框架选型与对比"&gt;第八章 框架选型与对比
&lt;/h2&gt;&lt;h3 id="81-langchain-vs-llamaindex"&gt;8.1 LangChain vs LlamaIndex
&lt;/h3&gt;&lt;p&gt;这是最常见的框架选型对比。两者定位不同，各有优势。&lt;/p&gt;
&lt;h4 id="核心定位对比"&gt;核心定位对比
&lt;/h4&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;LlamaIndex&lt;/th&gt;
&lt;th&gt;LangChain&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;主要关注点&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;高效组织和检索信息&lt;/td&gt;
&lt;td&gt;连接不同的 AI 工具和流程&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;主要用例&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;构建可搜索的信息数据库&lt;/td&gt;
&lt;td&gt;创建可执行多个任务的复杂 AI 系统&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据处理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;专注于组织不同类型的数据&lt;/td&gt;
&lt;td&gt;可以处理数据，但不是主要优势&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;集成&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;与现有数据协同工作&lt;/td&gt;
&lt;td&gt;更擅长连接不同的 AI 工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;复杂性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;基本任务更容易使用&lt;/td&gt;
&lt;td&gt;提供更多选项，学习更难&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;查询优化&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;内置功能加快和改善搜索&lt;/td&gt;
&lt;td&gt;通常需要手动优化搜索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;自定义&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;更少的更改选项&lt;/td&gt;
&lt;td&gt;允许广泛的自定义&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;学习曲线&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;通常可以快速学习&lt;/td&gt;
&lt;td&gt;需要更多时间掌握&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="关键差异点"&gt;关键差异点
&lt;/h4&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;LlamaIndex&lt;/th&gt;
&lt;th&gt;LangChain&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据索引&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;快速组织和分类大量信息，高效转化为嵌入&lt;/td&gt;
&lt;td&gt;模块化架构，设计定制解决方案&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;排名算法&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;根据语义相似性对文档排名&lt;/td&gt;
&lt;td&gt;将检索算法与 LLM 集成，生成上下文感知输出&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;性能效率&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;优先优化数据检索，快速准确访问&lt;/td&gt;
&lt;td&gt;强调灵活性和集成性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;上下文保留&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;基本上下文保留，不适合长时间交互&lt;/td&gt;
&lt;td&gt;先进上下文保留，适合长复杂对话&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;自定义&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;主要集中在索引和检索任务&lt;/td&gt;
&lt;td&gt;支持复杂工作流，广泛自定义选项&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="选型建议"&gt;选型建议
&lt;/h4&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;需求&lt;/th&gt;
&lt;th&gt;推荐框架&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;高效的索引和检索（RAG 核心）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LlamaIndex&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;灵活性和创造性生成&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LangChain&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;构建可搜索的信息数据库&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LlamaIndex&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;创建可执行多个任务的复杂 AI 系统&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LangChain&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;需要长对话上下文的聊天机器人&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LangChain&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;需要快速数据访问和简单搜索&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LlamaIndex&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;高度定制化需求&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LangChain&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;快速上手&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LlamaIndex&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一句话总结：&lt;strong&gt;LlamaIndex 是数据检索专家，LangChain 是流程编排通才&lt;/strong&gt;。如果你的核心痛点是&amp;quot;怎么把海量文档高效检索出来&amp;quot;，LlamaIndex 更专业；如果你要搭一个&amp;quot;能查资料、能调工具、能多轮对话&amp;quot;的复杂 Agent，LangChain 更合适。当然，两者可以混用——用 LlamaIndex 做检索层，用 LangChain 做编排层。&lt;/p&gt;
&lt;h3 id="82-多-agent-框架对比"&gt;8.2 多 Agent 框架对比
&lt;/h3&gt;&lt;p&gt;2026 年最热门的 Agent 编排框架对比：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;框架&lt;/th&gt;
&lt;th&gt;核心理念&lt;/th&gt;
&lt;th&gt;优势&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LangGraph&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;多 Agent 协作建模为有向图，节点是 Agent/工具，边是状态流转&lt;/td&gt;
&lt;td&gt;持久化执行、人工干预、状态管理强&lt;/td&gt;
&lt;td&gt;复杂有状态工作流&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CrewAI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;企业级工作流和工具集成，角色协作&lt;/td&gt;
&lt;td&gt;易用、内置工具集成&lt;/td&gt;
&lt;td&gt;企业级 Agent 工作流&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AutoGen&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;对话驱动的多 Agent&lt;/td&gt;
&lt;td&gt;平缓学习曲线、内置 LLM 集成&lt;/td&gt;
&lt;td&gt;对话式 Agent 协作&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AgentX&lt;/strong&gt;（华为云开源）&lt;/td&gt;
&lt;td&gt;中文支持完善&lt;/td&gt;
&lt;td&gt;国内生态&lt;/td&gt;
&lt;td&gt;国内企业场景&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="langgraph-vs-crewai"&gt;LangGraph vs CrewAI
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LangGraph&lt;/strong&gt;：底层、灵活、学习曲线陡。你要画图、定义状态、写 reducer。适合需要精确控制流程的复杂场景。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CrewAI&lt;/strong&gt;：上层、易用、学习曲线平缓。你定义角色和任务，框架帮你编排。适合快速搭建企业级工作流。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;选型原则：&lt;strong&gt;流程确定性高、需要精确控制 → LangGraph；快速验证、角色协作为主 → CrewAI&lt;/strong&gt;。&lt;/p&gt;
&lt;h4 id="langgraph-vs-autogen"&gt;LangGraph vs AutoGen
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LangGraph&lt;/strong&gt;：图驱动，状态在节点间流转，适合有明确流程的工作流。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AutoGen&lt;/strong&gt;：对话驱动，Agent 之间通过对话协作，适合探索性、开放式协作。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="83-langchain-vs-semantic-kernel"&gt;8.3 LangChain vs Semantic Kernel
&lt;/h3&gt;&lt;p&gt;Semantic Kernel 是微软开源的 AI 编排框架，与 LangChain 类似但生态不同：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;LangChain&lt;/th&gt;
&lt;th&gt;Semantic Kernel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;语言&lt;/td&gt;
&lt;td&gt;Python/JS/TS&lt;/td&gt;
&lt;td&gt;C#/Python/Java&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;生态&lt;/td&gt;
&lt;td&gt;LangGraph/LangSmith 全家桶&lt;/td&gt;
&lt;td&gt;微软 Azure 生态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;定位&lt;/td&gt;
&lt;td&gt;Agent 框架 + 编排运行时&lt;/td&gt;
&lt;td&gt;AI 编排 + 插件系统&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;优势&lt;/td&gt;
&lt;td&gt;社区活跃、组件丰富&lt;/td&gt;
&lt;td&gt;与 .NET 深度集成&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="84-框架选型决策树"&gt;8.4 框架选型决策树
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;你的需求是什么？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 需要开箱即用的 Agent（含上下文压缩、文件系统、子 Agent）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─→ Deep Agents
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 需要高度可定制的单 Agent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─→ LangChain (create_agent)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 需要复杂有状态工作流 / 多 Agent 编排
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─→ LangGraph
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 需要高效数据索引和检索（RAG 核心）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─→ LlamaIndex（或 LangChain Retrievers）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 需要追踪、调试、评估
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─→ LangSmith（适用于以上所有框架）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 需要部署为 API 服务
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─→ LangDeployment（原 LangGraph Platform）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 团队是 .NET 技术栈，深度依赖 Azure
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─→ Semantic Kernel
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 快速搭建企业级角色协作 Agent，不想学图编程
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─→ CrewAI
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 对话式多 Agent 协作，探索性强
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └─→ AutoGen
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─ 国内企业场景，需要完善中文支持
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─→ AgentX（华为云）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="85-什么时候该手搓不用框架"&gt;8.5 什么时候该手搓（不用框架）
&lt;/h3&gt;&lt;p&gt;框架不是银弹。以下场景，手搓可能比用框架更好：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;极简需求&lt;/strong&gt;：只是调一次模型 API，一个 &lt;code&gt;requests.post&lt;/code&gt; 搞定，引入 LangChain 反而是负担&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;极致性能&lt;/strong&gt;：框架的抽象层有开销，高 QPS 场景手搓更可控&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特殊流程&lt;/strong&gt;：你的工作流极其特殊，框架的抽象反而碍事&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;学习目的&lt;/strong&gt;：手搓一遍 ReAct 循环，能深刻理解框架在帮你做什么&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 手搓一个最小 ReAct Agent（不用任何框架）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;openai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;react_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_iter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;手搓 ReAct：思考→行动→观察→思考...&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;你是一个能使用工具的助手。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;可用工具：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;当你要使用工具时，输出 JSON：&lt;/span&gt;&lt;span class="se"&gt;{{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;action&amp;#34;: &amp;#34;工具名&amp;#34;, &amp;#34;input&amp;#34;: &amp;#34;参数&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;}}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;当你有最终答案时，输出：&lt;/span&gt;&lt;span class="se"&gt;{{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;action&amp;#34;: &amp;#34;final_answer&amp;#34;, &amp;#34;input&amp;#34;: &amp;#34;答案&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;}}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_iter&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;thought&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;assistant&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;thought&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 解析 action 并执行（省略解析逻辑）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;final_answer&amp;#34;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;thought&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;thought&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 执行工具，把结果作为 observation 喂回去&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;观察结果：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool_result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;达到最大迭代次数&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;手搓的价值在于理解原理。知道框架在帮你做什么，你才能判断什么时候该用框架、什么时候该绕过。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;第八章实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LlamaIndex 擅长检索，LangChain 擅长编排，两者可混用。&lt;/li&gt;
&lt;li&gt;LangGraph 灵活但陡，CrewAI 易用但浅，按&amp;quot;确定性控制需求&amp;quot;选。&lt;/li&gt;
&lt;li&gt;决策树从需求出发，不要&amp;quot;先选框架再找需求&amp;quot;。&lt;/li&gt;
&lt;li&gt;极简需求手搓更干净，框架的抽象层在简单场景是负担。&lt;/li&gt;
&lt;li&gt;手搓一遍 ReAct 循环是理解 Agent 的最佳方式。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第九章-最佳实践与工程落地"&gt;第九章 最佳实践与工程落地
&lt;/h2&gt;&lt;h3 id="91-状态设计最佳实践"&gt;9.1 状态设计最佳实践
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;使用 TypedDict 定义 State，清晰且类型安全&lt;/li&gt;
&lt;li&gt;合理使用 Reducer：消息列表用 &lt;code&gt;operator.add&lt;/code&gt; 累加，配置类用覆盖模式&lt;/li&gt;
&lt;li&gt;使用多 Schema 设计（InputState/OutputState/OverallState）分离关注点&lt;/li&gt;
&lt;li&gt;并行节点使用自定义 Reducer 避免覆盖问题&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;operator&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 多 Schema 设计：分离输入、输出、内部状态&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InputState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;用户输入的 State（只含用户能提供的字段）&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OutputState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;输出给用户的 State（只含需要返回的字段）&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OverallState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OutputState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;内部完整 State（含所有中间字段）&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;retrieved_docs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;iteration_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="c1"&gt;# 覆盖模式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 自定义 Reducer：解决并行节点覆盖问题&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;merge_dicts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;并行节点的 dict 合并：递归合并而非覆盖&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ParallelState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 多个并行节点都写这个字段，用自定义 Reducer 合并&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;merge_dicts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="92-持久化最佳实践"&gt;9.2 持久化最佳实践
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;开发阶段：InMemorySaver（最快）&lt;/li&gt;
&lt;li&gt;单机生产：SqliteSaver&lt;/li&gt;
&lt;li&gt;多进程/分布式生产：&lt;strong&gt;PostgresSaver&lt;/strong&gt;（推荐）&lt;/li&gt;
&lt;li&gt;长期记忆使用 BaseStore（跨线程共享用户偏好、知识积累）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.checkpoint.postgres&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PostgresSaver&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.store.postgres&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PostgresStore&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;contextlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asynccontextmanager&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 生产级配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;DB_URI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;postgresql://user:pass@localhost:5432/langgraph&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 持久化 + 长期记忆&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PostgresSaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_conn_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB_URI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PostgresStore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_conn_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB_URI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 长期记忆：记住用户偏好，跨对话线程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_user_preference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user_preference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="93-流式输出最佳实践"&gt;9.3 流式输出最佳实践
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;用户交互场景优先使用 &lt;code&gt;stream_mode=&amp;quot;messages&amp;quot;&lt;/code&gt; 实现 Token 级流式&lt;/li&gt;
&lt;li&gt;调试场景使用 &lt;code&gt;stream_mode=&amp;quot;updates&amp;quot;&lt;/code&gt; 观察状态变化&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;get_stream_writer()&lt;/code&gt; 发送自定义进度数据&lt;/li&gt;
&lt;li&gt;LangGraph &amp;gt;= 1.1 推荐使用 &lt;code&gt;version=&amp;quot;v2&amp;quot;&lt;/code&gt; 格式&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_stream_writer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;long_running_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;模拟长时间运行节点，发送自定义进度&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_stream_writer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;加载模型&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;检索文档&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;生成回复&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;格式化输出&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;progress&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;步骤 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# ... 实际工作 ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;answer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;完成&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 客户端接收自定义流&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;复杂问题&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stream_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;custom&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;custom&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;[进度] &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;progress&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="94-人工干预最佳实践"&gt;9.4 人工干预最佳实践
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;关键决策使用 &lt;code&gt;interrupt()&lt;/code&gt; 暂停等待人工审核&lt;/li&gt;
&lt;li&gt;危险工具调用（删除、支付、发邮件）执行前审核&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;Command(resume=...)&lt;/code&gt; 恢复执行&lt;/li&gt;
&lt;li&gt;并行多中断使用 &lt;code&gt;resume_map&lt;/code&gt; 一次性恢复&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langgraph.types&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;interrupt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dangerous_action_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;执行危险操作前的审核&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;action_desc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;即将执行：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pending_action&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# interrupt 暂停，把决策权交给人类&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;approval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;interrupt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;action_approval&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;action_desc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;severity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;high&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;approval&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;approved&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 执行危险操作&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;execute_dangerous_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;executed&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;approval&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;modified&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 人类修改了操作&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;execute_dangerous_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;modified&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;executed_modified&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;操作被拒绝&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;rejected&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 恢复执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resume&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;approved&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="95-可观测性最佳实践"&gt;9.5 可观测性最佳实践
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;必须&lt;/strong&gt;配置 LangSmith 追踪（&lt;code&gt;LANGSMITH_TRACING=true&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;设置 LangSmith Engine 自动监控和问题检测&lt;/li&gt;
&lt;li&gt;利用追踪数据定位性能瓶颈和失败模式&lt;/li&gt;
&lt;li&gt;用数据集做回归测试，评估 Agent 质量&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LANGSMITH_TRACING&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LANGSMITH_API_KEY&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ls__xxx&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LANGSMITH_PROJECT&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;prod-agent-v2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 给重要调用打标签，方便在 LangSmith 筛选&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.tracers.context&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tracing_v2_enabled&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;tracing_v2_enabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;project_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;prod-agent-v2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;customer-service&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;v2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;12345&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;session&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 这次调用在 LangSmith 会带上 tag 和 metadata，方便筛选分析&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="96-模型与工具最佳实践"&gt;9.6 模型与工具最佳实践
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;使用 LangChain 标准模型接口，保持模型可替换性&lt;/li&gt;
&lt;li&gt;工具描述要清晰准确，影响 Agent 调用成功率&lt;/li&gt;
&lt;li&gt;工具集（Toolkits）按场景组织，避免过多工具导致选择困难&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;bind_tools()&lt;/code&gt; 将工具绑定到模型&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BaseToolkit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 工具描述黄金法则：写&amp;#34;什么场景该调我&amp;#34;，不写&amp;#34;我是干嘛的&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query_sales_db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date_range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;查询销售数据库。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 什么时候用我：当用户问&amp;#34;某段时间某个地区的销售额/订单量/客户数&amp;#34;时。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 参数说明：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - date_range: 日期范围，格式 &amp;#34;2024-01-01~2024-01-31&amp;#34; 或 &amp;#34;最近7天&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - region: 地区，如 &amp;#34;华东&amp;#34;、&amp;#34;华南&amp;#34;、&amp;#34;全国&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 返回：包含销售额、订单量、客单价的 JSON。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;query_db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date_range&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 工具不宜过多：超过 10 个工具时，模型选择准确率显著下降&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 解决方案：用路由 Agent 先选工具集，再传给执行 Agent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="97-模块化设计最佳实践"&gt;9.7 模块化设计最佳实践
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;复杂工作流拆分为子图（Subgraphs），每个子图独立状态管理&lt;/li&gt;
&lt;li&gt;使用 DSL 驱动 + 动态图构建实现可配置工作流（类 Dify 模式）&lt;/li&gt;
&lt;li&gt;节点职责单一：节点做工作，边决定下一步&lt;/li&gt;
&lt;li&gt;支持工作流的可视化（Mermaid 图）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 子图：把复杂工作流拆成可复用的模块&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_research_subgraph&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;研究子图：检索→分析→总结&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sub_graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ResearchState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sub_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;retrieve&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;retrieve_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sub_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;analyze&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;analyze_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sub_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;summarize&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;summarize_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sub_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;retrieve&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sub_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;retrieve&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;analyze&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sub_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;analyze&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;summarize&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sub_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;summarize&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sub_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 主图中嵌入子图&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;main_graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OverallState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;main_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;research&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;build_research_subgraph&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;# 子图作为节点&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;main_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;write&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;write_node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;main_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;research&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;main_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;research&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;write&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;main_graph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;write&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="98-生产部署最佳实践"&gt;9.8 生产部署最佳实践
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;使用 PostgreSQL Checkpointer 实现持久化和容错恢复&lt;/li&gt;
&lt;li&gt;异步 API（&lt;code&gt;ainvoke&lt;/code&gt;/&lt;code&gt;astream&lt;/code&gt;）提升并发性能&lt;/li&gt;
&lt;li&gt;配置超时和重试机制&lt;/li&gt;
&lt;li&gt;实现健康检查和监控告警&lt;/li&gt;
&lt;li&gt;CI/CD 管道集成 LangSmith 评估&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tenacity&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stop_after_attempt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wait_exponential&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 异步 + 重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;stop_after_attempt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;wait_exponential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_agent_async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;configurable&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;thread_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ainvoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;)]},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 并发处理多个请求&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_batch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;call_agent_async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;inp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;thread_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;inp&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;return_exceptions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="99-常见陷阱与解决方案"&gt;9.9 常见陷阱与解决方案
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;陷阱&lt;/th&gt;
&lt;th&gt;原因&lt;/th&gt;
&lt;th&gt;解决方案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;并行节点结果丢失&lt;/td&gt;
&lt;td&gt;state 字段默认覆盖写入&lt;/td&gt;
&lt;td&gt;使用自定义 Reducer 改为追加语义&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent 无限循环&lt;/td&gt;
&lt;td&gt;缺少终止条件&lt;/td&gt;
&lt;td&gt;添加迭代计数器和完成标志&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;状态臃肿&lt;/td&gt;
&lt;td&gt;消息列表无限增长&lt;/td&gt;
&lt;td&gt;实现上下文压缩/摘要机制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;工具调用失败无处理&lt;/td&gt;
&lt;td&gt;未处理异常&lt;/td&gt;
&lt;td&gt;使用 ToolNode 自动处理工具错误&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;流式中断未处理&lt;/td&gt;
&lt;td&gt;忽略 &lt;code&gt;__interrupt__&lt;/code&gt; 事件&lt;/td&gt;
&lt;td&gt;检查流中的中断信息并处理&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 防止 Agent 无限循环：加迭代计数器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;should_continue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;iteration_count&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# 最大 10 轮&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;END&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;continue&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 上下文压缩：消息太多时自动摘要&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;compress_if_needed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# 超过 20 条消息就压缩&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SystemMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;把以下对话压缩成一段摘要&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# 保留最近 4 条不压缩&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="910-技术栈推荐"&gt;9.10 技术栈推荐
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;层级&lt;/th&gt;
&lt;th&gt;推荐技术&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;模型&lt;/td&gt;
&lt;td&gt;GPT-5.5 / Claude Sonnet 4 / Gemini 2.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embedding&lt;/td&gt;
&lt;td&gt;OpenAI Embeddings / M3E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;向量数据库&lt;/td&gt;
&lt;td&gt;Chroma（开发）/ pgvector（生产）/ MyScale（SQL+向量）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;持久化&lt;/td&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;编排&lt;/td&gt;
&lt;td&gt;LangGraph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent&lt;/td&gt;
&lt;td&gt;LangChain create_agent / Deep Agents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;监控&lt;/td&gt;
&lt;td&gt;LangSmith&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;部署&lt;/td&gt;
&lt;td&gt;LangDeployment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;前端&lt;/td&gt;
&lt;td&gt;Gradio / Streamlit / Agent Chat UI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="911-从-claude-code-skill-机制中学到的工程智慧"&gt;9.11 从 Claude Code Skill 机制中学到的工程智慧
&lt;/h3&gt;&lt;p&gt;在研究 LangChain 的工具机制时，有必要横向对比 Claude Code 的 Skill 机制。虽然两者面向不同场景（LangChain 是通用 Agent 框架，Claude Code 是编程助手），但 Skill 机制沉淀的工程经验对设计任何 Agent 工具系统都有启发。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心洞察一：工具描述是触发器，不是说明书。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Claude Code 的 Skill 机制揭示了一个反直觉的事实：模型决定用不用某个工具/技能，&lt;strong&gt;唯一的依据就是那行 description&lt;/strong&gt;。它没读过正文，不知道你内容写得多用心。description 没写好，正文写出花来也白搭。Anthropic 内部甚至给 description 设了硬性预算：整张工具清单只允许占用 context 窗口的 1%，单个工具描述最多 250 个字符。&lt;/p&gt;
&lt;p&gt;这对 LangChain 的工具设计直接适用：&lt;code&gt;@tool&lt;/code&gt; 的 docstring 不是写给人看的摘要，是写给模型看的触发条件。不要写&amp;quot;这是一个查询数据库的工具&amp;quot;（人类视角），要写&amp;quot;当用户询问销售额、订单量、客户数等业务指标时使用此工具&amp;quot;（模型视角）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心洞察二：工具越多越糊涂。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Claude Code 发现：装太多 Skill 反而都不触发。因为 1% 的 context 预算被挤爆后，所有 description 被压缩，最后变成一排只有名字的哑巴。LangChain 同理：给 Agent 挂太多工具，模型选择准确率显著下降。解法是用分层路由——先由一个轻量 Agent 判断意图、选工具集，再把选中的少量工具传给执行 Agent。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心洞察三：验证类工具回报最大。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Anthropic 内部实测，让 Agent 能&amp;quot;自己验证工作成果&amp;quot;的工具，对输出质量提升最明显。原话甚至说值得让一个工程师花一整周专门打磨。在 LangChain 体系里，这意味着你的 Agent 不能只会&amp;quot;干活&amp;quot;，还要会&amp;quot;检查自己干得对不对&amp;quot;——加一个验证节点，用断言检查输出格式、用测试用例验证逻辑正确性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心洞察四：坑点清单比操作说明值钱。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Skill 正文里含金量最高的不是&amp;quot;怎么做&amp;quot;，而是&amp;quot;别踩什么坑&amp;quot;。同样，LangChain 工具的 docstring 里，最有价值的是边界条件和失败模式描述。告诉模型&amp;quot;这个工具在什么情况下会失败、失败时返回什么&amp;quot;，比告诉它&amp;quot;成功时返回什么&amp;quot;更重要。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LangChain 工具设计 vs Claude Code Skill 设计的共通原则：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 1. description 是触发条件，不是说明书（≤250字符） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 2. 工具贵精不贵多，多了用分层路由 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 3. 验证类工具回报最大（让 Agent 自检） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 4. 坑点清单 &amp;gt; 操作说明（写边界条件和失败模式） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 5. 按需加载：不用的工具别占 context │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;第九章实践要点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;状态设计用多 Schema 分离关注点，并行节点务必用自定义 Reducer。&lt;/li&gt;
&lt;li&gt;生产环境 PostgresSaver + LangSmith 追踪 + 异步 API，三件套缺一不可。&lt;/li&gt;
&lt;li&gt;工具描述写&amp;quot;什么场景该调我&amp;quot;而非&amp;quot;我是干嘛的&amp;quot;，工具数控制在 10 个以内。&lt;/li&gt;
&lt;li&gt;防无限循环加计数器，防状态臃肿加上下文压缩。&lt;/li&gt;
&lt;li&gt;从 Skill 机制学到的：验证工具优先做，坑点清单比操作说明值钱。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="结尾"&gt;结尾
&lt;/h2&gt;&lt;h3 id="核心知识点回顾"&gt;核心知识点回顾
&lt;/h3&gt;&lt;p&gt;本篇从定位到落地，把 LangChain 体系拆解了一遍。核心知识点回顾如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;核心理念&lt;/strong&gt;：Agent = Model + Harness。LangChain 提供的是&amp;quot;模型循环周围的一切&amp;quot;——提示词、工具、中间件。你的工作大多是配置 harness，不是改模型。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;五层生态&lt;/strong&gt;：Deep Agents（开箱即用）→ LangChain（可定制 harness）→ LangGraph（图编排运行时）→ LangSmith（可观测性）→ LangDeployment（部署）。上层省事但灵活度低，下层灵活但要多写代码。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;六大组件&lt;/strong&gt;：Model I/O（说）、Data Connection（找资料）、Chains（串）、Memory（记）、Agents（想）、Callbacks（观察）。完整覆盖 LLM 应用链路。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LCEL&lt;/strong&gt;：管道符语法 + Runnable 统一接口，天然支持流式/异步/批量/并行/回退。是新代码首选，传统 Chains 只用于维护旧代码。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LangGraph&lt;/strong&gt;：把工作流建模为有向图，State + Nodes + Edges + Reducer 协同工作。解决传统 Agent 的流程不可控、状态管理弱、无持久化、无法人工干预、循环工作流难五大痛点。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;人工干预&lt;/strong&gt;：interrupt() 暂停 + Command(resume=&amp;hellip;) 恢复，是危险操作审核的标准范式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LangSmith&lt;/strong&gt;：框架无关的可观测性平台，设置环境变量即自动追踪。追踪、调试、评估、监控四件套，是 Agent 工程化的基础设施。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;部署&lt;/strong&gt;：LangServe 已弃用，新项目用 LangDeployment（原 LangGraph Platform），支持 Server/Studio/Cloud/自托管。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;选型&lt;/strong&gt;：LlamaIndex 擅长检索，LangChain 擅长编排，LangGraph 灵活但陡，CrewAI 易用但浅。从需求出发选框架，不要先选框架再找需求。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;工程智慧&lt;/strong&gt;：工具描述是触发器不是说明书，工具贵精不贵多，验证类工具回报最大，坑点清单比操作说明值钱。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="主题关联"&gt;主题关联
&lt;/h3&gt;&lt;p&gt;本篇是 AI 知识系列的第 04 篇，与系列其他篇目的关联：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LLM 基础篇&lt;/strong&gt;：理解 Transformer 架构和注意力机制，是理解&amp;quot;模型为什么需要 prompt 工程&amp;quot;的基础&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAG 深度篇&lt;/strong&gt;：本篇第三章的 Data Connection 是 RAG 的骨架，RAG 篇会展开检索策略、重排序、混合检索等进阶主题&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent 设计篇&lt;/strong&gt;：本篇的 Agents 和 LangGraph 章节是 Agent 设计的工程实现，Agent 篇会展开 ReAct/Plan-and-Execute/Reflection 等认知架构&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prompt 工程篇&lt;/strong&gt;：本篇的 PromptTemplate 是 Prompt 工程的代码化，Prompt 篇会展开 CoT/Few-shot/自洽性等技巧&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Code / Skill 机制篇&lt;/strong&gt;：本篇第九章对比了 Skill 机制，两者都揭示了&amp;quot;工具描述质量决定 Agent 成败&amp;quot;的共通规律&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="进一步阅读"&gt;进一步阅读
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;主题&lt;/th&gt;
&lt;th&gt;资源&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LangChain 官方文档&lt;/td&gt;
&lt;td&gt;&lt;a class="link" href="https://python.langchain.com/docs/concepts/lcel/" target="_blank" rel="noopener"
&gt;https://python.langchain.com/docs/concepts/lcel/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangGraph 深度教程&lt;/td&gt;
&lt;td&gt;&lt;a class="link" href="https://baiweijieku.github.io/posts/langgraph/" target="_blank" rel="noopener"
&gt;https://baiweijieku.github.io/posts/langgraph/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangChain vs LlamaIndex&lt;/td&gt;
&lt;td&gt;&lt;a class="link" href="https://www.myscale.com/blog/zh/llamaindex-vs-langchain-detailed-comparison/" target="_blank" rel="noopener"
&gt;https://www.myscale.com/blog/zh/llamaindex-vs-langchain-detailed-comparison/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangGraph 多 Agent 工作流&lt;/td&gt;
&lt;td&gt;&lt;a class="link" href="https://www.langchain.com/blog/langgraph-multi-agent-workflows" target="_blank" rel="noopener"
&gt;https://www.langchain.com/blog/langgraph-multi-agent-workflows&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic Skill 实战博客&lt;/td&gt;
&lt;td&gt;&lt;a class="link" href="https://claude.com/blog/lessons-from-building-claude-code-how-we-use-skills" target="_blank" rel="noopener"
&gt;https://claude.com/blog/lessons-from-building-claude-code-how-we-use-skills&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangChain 核心组件解读&lt;/td&gt;
&lt;td&gt;&lt;a class="link" href="https://cloud.tencent.com/developer/article/2324297" target="_blank" rel="noopener"
&gt;https://cloud.tencent.com/developer/article/2324297&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026 Agent 框架更新&lt;/td&gt;
&lt;td&gt;&lt;a class="link" href="https://learnagent.org/library/playbooks/framework-updates-2026/" target="_blank" rel="noopener"
&gt;https://learnagent.org/library/playbooks/framework-updates-2026/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;架构会演进，API 会更迭，但&amp;quot;模型 + 框架 = Agent&amp;quot;的公式不变，&amp;ldquo;节点做工作，边决定下一步&amp;quot;的图思维不变，&amp;ldquo;工具描述决定 Agent 成败&amp;quot;的规律不变。抓住这些不变量，框架的版本号再怎么跳，你都能从容应对。&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;</description></item><item><title>LLM工具调用深度解析——从Function Calling到MCP</title><link>https://blog.irudder.me/ai/ai-systematization/03-LLM-Tool-Calling-Deep-Dive.html</link><pubDate>Sun, 26 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/ai-systematization/03-LLM-Tool-Calling-Deep-Dive.html</guid><description>&lt;h1 id="llm工具调用深度解析从function-calling到mcp"&gt;LLM工具调用深度解析——从Function Calling到MCP
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;本文是「AI 知识体系深度解析」系列的第三篇。LLM 的工具调用能力是 Agent 系统的地基：没有它，模型只是一个会聊天的文字盒子。从 2023 年 OpenAI 推出 Function Calling，到 2024 年 Anthropic 发布 MCP 协议，再到 2025 年 Skill 与 A2A 的出现，&amp;ldquo;让模型真正能做事&amp;rdquo; 这件事经历了一整条技术栈的演进。本文将这条栈从底到顶完整拆开——从模型如何学会输出 JSON、到工具如何标准化接入、再到多个 Agent 如何跨进程协作，一次性建立完整的知识地图。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="核心问题列表"&gt;核心问题列表
&lt;/h2&gt;&lt;p&gt;阅读本文，你将能够回答以下关键问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Function Calling 到底是谁在执行工具？&lt;/strong&gt; 模型只负责&amp;quot;决策&amp;quot;，代码负责&amp;quot;执行&amp;quot;，这个分工为何是整个机制的基石？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;大模型是天生就会调工具的吗？&lt;/strong&gt; SFT 和 RLHF 各自解决了什么问题？为什么缺一不可？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MCP 和 Function Calling 是竞争关系吗？&lt;/strong&gt; 它们到底处于不同的抽象层次还是同一层面？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;推理模型为什么曾经不支持工具调用？&lt;/strong&gt; 生成范式的冲突到底是什么？后来又是怎么解决的？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skill 和 MCP 有什么区别？&lt;/strong&gt; &amp;ldquo;操作手册&amp;quot;和&amp;quot;工具箱&amp;quot;是怎么配合工作的？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A2A 和 MCP 有什么区别？&lt;/strong&gt; 为什么复杂 Agent 系统里两者都要用？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSE、WebSocket、WebRTC、stdio 各自适合什么场景？&lt;/strong&gt; 通信协议该怎么选？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM 网关和普通 API 网关有什么本质区别？&lt;/strong&gt; 语义缓存为什么是 LLM 特有的能力？&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="引言从一个错觉说起"&gt;引言：从一个&amp;quot;错觉&amp;quot;说起
&lt;/h2&gt;&lt;p&gt;很多人第一次接触 LLM 工具调用时，会有一个直觉性的误解：&lt;strong&gt;&amp;ldquo;模型自己去访问网络、查数据库，然后把结果返回给用户。&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这句话里藏着一个根本性错误——模型有直接执行代码的能力吗？它能联网吗？答案是不能。大语言模型在预训练阶段学的是&amp;quot;给定前面的文字，预测下一个 token&amp;rdquo;，整个训练过程完全在文本空间里进行，模型从未见过&amp;quot;工具调用&amp;quot;这件事。哪怕你在 prompt 里写&amp;quot;你可以调用天气 API&amp;quot;，没经过专门训练的模型也只会生成一段自然语言描述——&amp;ldquo;我需要调用天气 API 来回答你&amp;rdquo;——而不是输出一段可以被程序解析和执行的 JSON 调用请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;描述一个意图&lt;/strong&gt;和&lt;strong&gt;输出可执行的结构化指令&lt;/strong&gt;，这两件事之间有本质的差距。&lt;/p&gt;
&lt;p&gt;正是为了跨越这道鸿沟，整个 LLM 工具调用的技术栈被一层层搭建起来：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ A2A (Agent 间协作) │ ← 横向：多Agent通信
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Skill (任务流程知识化) │ ← 第3层：操作手册
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ MCP (工具标准化接入协议) │ ← 第2层：工具箱
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Function Calling (模型调用语言) │ ← 第1层：调用协议
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LLM (大语言模型本体) │ ← 地基
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↑ 底层 通信协议层(横切) 顶层 ↑
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (SSE/WebSocket/WebRTC/stdio) (LLM Gateway 横切中间件)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;本文将按&amp;quot;从底到顶&amp;quot;的顺序，把这张图里的每一层拆开讲透。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第一章function-calling-原理"&gt;第一章：Function Calling 原理
&lt;/h2&gt;&lt;h3 id="11-function-calling-解决了什么问题"&gt;1.1 Function Calling 解决了什么问题
&lt;/h3&gt;&lt;p&gt;在 Function Calling 出现之前，想让模型帮你调工具，完全靠解析自然语言。模型输出&amp;quot;我需要查一下北京的天气&amp;quot;，你再写 &lt;code&gt;if/else&lt;/code&gt; 判断它&amp;quot;说&amp;quot;的是要查天气，然后手动去调 API。这个做法极其脆弱——模型换个说法，你的 &lt;code&gt;if/else&lt;/code&gt; 就失配了，也根本没办法标准化对接。&lt;/p&gt;
&lt;p&gt;Function Calling 的核心改进是：&lt;strong&gt;模型不再&amp;quot;说&amp;quot;要调工具，而是直接输出一段结构化的 JSON&lt;/strong&gt;，开发者按格式解析就行，准确率大幅提升，也有了统一标准可以对接。这套机制由 OpenAI 在 2023 年推出，现在 Claude、Gemini、Qwen 等主流模型都支持。&lt;/p&gt;
&lt;h3 id="12-三个角色把-function-calling-理解成一场任务委托"&gt;1.2 三个角色：把 Function Calling 理解成一场任务委托
&lt;/h3&gt;&lt;p&gt;理解 Function Calling 的关键是搞清楚&amp;quot;谁做什么&amp;quot;。可以把这套流程理解成一场&amp;quot;任务委托&amp;quot;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;比喻&lt;/th&gt;
&lt;th&gt;职责&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;开发者&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HR&lt;/td&gt;
&lt;td&gt;给每个工具写&amp;quot;职位说明书&amp;quot;（JSON schema），告诉模型有哪些工具、能做什么、需要什么参数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;模型&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;经理&lt;/td&gt;
&lt;td&gt;读完说明书后决定&amp;quot;调哪个工具、参数填什么&amp;quot;，把指令下达出来&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;宿主代码&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;员工&lt;/td&gt;
&lt;td&gt;真正去跑函数、访问网络、查数据库，把结果汇报回来&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：模型全程只是在&amp;quot;下指令&amp;quot;，它不亲自执行任何代码，也没有直接访问网络的权限。执行的事一律由宿主程序代码完成。这个&amp;quot;模型决策、代码执行&amp;quot;的分工是整个机制的核心设计——LLM 擅长理解意图和推理，但不应该有直接操作系统资源的权限；宿主程序负责执行，可以做权限控制、参数校验、执行沙箱等安全措施。&lt;/p&gt;
&lt;h3 id="13-工具定义schema-的每个字段都有含义"&gt;1.3 工具定义：schema 的每个字段都有含义
&lt;/h3&gt;&lt;p&gt;工具 schema 就是一份结构化的&amp;quot;工具说明书&amp;quot;，用 JSON 格式写：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;function&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;function&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;get_weather&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 工具的唯一标识&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;查询指定城市的实时天气，包含气温、天气状况、风向风速，仅支持中国大陆城市&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;parameters&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;城市名称，如「北京」「上海」，不要带省份前缀&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;unit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;enum&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;celsius&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fahrenheit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;温度单位，默认用摄氏度&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;required&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中最关键的字段是 &lt;code&gt;description&lt;/code&gt;。如果 description 写得含糊（比如只写&amp;quot;获取天气&amp;quot;），模型会&amp;quot;瞎猜&amp;quot;——拿到一个带英文名的城市也照样调，拿到&amp;quot;这周天气如何&amp;quot;这种时间跨度不对的问题也硬往里塞。模型在决定&amp;quot;要不要调这个工具、参数怎么填&amp;quot;的时候，能依赖的唯一依据就是这段描述。写得越清晰，模型的选择越准确。&lt;/p&gt;
&lt;h3 id="14-完整调用流程两轮对话加中间执行"&gt;1.4 完整调用流程：两轮对话加中间执行
&lt;/h3&gt;&lt;p&gt;Function Calling 的运行时本质上是&amp;quot;两轮对话 + 中间执行&amp;quot;的闭环：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;用户&lt;/span&gt; &lt;span class="err"&gt;模型&lt;/span&gt; &lt;span class="err"&gt;宿主代码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│────&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;北京天气？&amp;#34;&lt;/span&gt; &lt;span class="err"&gt;────→│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;携带&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;判断&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;需要调工具&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│←─&lt;/span&gt; &lt;span class="n"&gt;finish_reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;────│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tool_calls&amp;#34;&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│────&lt;/span&gt; &lt;span class="err"&gt;执行&lt;/span&gt; &lt;span class="n"&gt;get_weather&lt;/span&gt; &lt;span class="err"&gt;─→│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;北京&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│←────&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;晴,15°C&amp;#34;&lt;/span&gt; &lt;span class="err"&gt;───────│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;拿到结果&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;生成答案&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│←──&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;北京今天晴朗...&amp;#34;&lt;/span&gt; &lt;span class="err"&gt;─│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第一轮，你把工具列表和用户的问题一起传给模型。模型如果判断需要调工具，就不直接输出最终答案，而是输出一个 &lt;code&gt;finish_reason&lt;/code&gt; 为 &lt;code&gt;&amp;quot;tool_calls&amp;quot;&lt;/code&gt; 的响应，里面包含要调用的工具名和参数——这是个明确信号，告诉你&amp;quot;我需要工具帮助，还没准备好给答案&amp;quot;。&lt;/p&gt;
&lt;p&gt;中间环节交给你的代码：解析 &lt;code&gt;tool_calls&lt;/code&gt;，找到对应的函数执行，拿到结果。&lt;/p&gt;
&lt;p&gt;第二轮，把工具执行结果以 &lt;code&gt;role: &amp;quot;tool&amp;quot;&lt;/code&gt; 的消息塞回对话历史，再次调用模型。这次模型有了工具结果，有了充分信息，才给出最终的自然语言答案。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;北京今天天气怎么样？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 第一轮：把工具定义和问题一起传给模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tool_choice&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;auto&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;# auto 让模型自己判断，也可设 required 强制调&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;finish_reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tool_calls&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# 模型要调工具&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tool_call&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;func_args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_call&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# {&amp;#34;city&amp;#34;: &amp;#34;北京&amp;#34;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 中间执行：你的代码真正去跑函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;func_args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;city&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;今天晴，15°C，东北风 3 级&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 第二轮：把工具结果塞回对话，再问一次模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tool&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;tool_call_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool_call&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 和 tool_calls 里的 id 对应&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;final&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;final&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 输出：北京今天天气晴朗，气温 15°C，东北风 3 级，适合外出。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="15-并行工具调用"&gt;1.5 并行工具调用
&lt;/h3&gt;&lt;p&gt;如果用户一口气问了好几件事——&amp;ldquo;帮我查北京、上海、广州三个城市的天气&amp;rdquo;——模型可以在一次响应里同时输出多个 &lt;code&gt;tool_calls&lt;/code&gt;（它是一个列表）。你的代码可以同时执行这些工具（比如用 &lt;code&gt;asyncio.gather&lt;/code&gt;），拿到所有结果后一次性塞回对话，再调一次模型拿到综合答案。&lt;/p&gt;
&lt;p&gt;整个过程从&amp;quot;两轮对话 × N 个工具串行&amp;quot;压缩成了&amp;quot;一轮对话 + 并行执行&amp;quot;，总耗时大幅降低。&lt;strong&gt;但前提是这几个工具之间没有依赖关系&lt;/strong&gt;：查北京和上海天气互不影响，可以并行；但&amp;quot;先查用户订单号，再用订单号查物流&amp;quot;，第二个调用依赖第一个的结果，只能串行，模型也会正确地分两轮输出。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_tool_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_call&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;并行执行单个工具调用&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;func_args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_call&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 这里 dispatch 到真实函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;dispatch_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_call&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;func_args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 并行执行模型一次返回的多个 tool_calls&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;execute_tool_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 把所有结果塞回对话&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tool&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;tool_call_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="本章实践要点"&gt;本章实践要点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;description 是灵魂&lt;/strong&gt;：工具描述写得越清晰，模型选择越准确。务必写明适用范围、参数格式、限制条件。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型只决策不执行&lt;/strong&gt;：永远不要让模型直接操作系统资源，执行逻辑放在宿主代码里，便于权限控制和沙箱隔离。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并行调用要判断依赖&lt;/strong&gt;：无依赖的工具用并行执行降低延迟，有依赖的必须串行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tool_call_id 要对应&lt;/strong&gt;：第二轮把结果塞回去时，&lt;code&gt;tool_call_id&lt;/code&gt; 必须和 &lt;code&gt;tool_calls&lt;/code&gt; 里的 id 一一对应。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="第二章function-calling-训练"&gt;第二章：Function Calling 训练
&lt;/h2&gt;&lt;h3 id="21-原始-llm-为什么不会调工具"&gt;2.1 原始 LLM 为什么不会调工具
&lt;/h3&gt;&lt;p&gt;想象一个人从出生到成年，只生活在文字的世界里，读过几乎所有的书，却从没接触过任何工具——没用过锤子、没开过车、也没见过 API。你突然跟他说&amp;quot;去帮我查一下天气 API&amp;quot;，他最多只会用语言描述&amp;quot;我需要查天气 API 来获取数据……&amp;quot;，绝对不会真的去操作工具。&lt;/p&gt;
&lt;p&gt;大语言模型在预训练阶段经历的就是这样一个过程。预训练的目标是&amp;quot;预测下一个 token&amp;quot;，整个训练完全在文本空间里进行，模型从未见过&amp;quot;工具调用&amp;quot;这件事。预训练语料里有代码、有文档、有对话，但几乎没有&amp;quot;给定一组工具 schema，该在什么场景输出什么 JSON&amp;quot;这样的成对样本。&lt;/p&gt;
&lt;p&gt;所以工具调用能力不是天生的，是后天&amp;quot;教&amp;quot;出来的。怎么教？靠两个阶段：&lt;strong&gt;SFT 教会怎么调，RLHF 教会什么时候调&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="22-第一阶段sft让模型见过工具调用"&gt;2.2 第一阶段：SFT，让模型&amp;quot;见过&amp;quot;工具调用
&lt;/h3&gt;&lt;p&gt;SFT（Supervised Fine-Tuning，监督微调）的核心思路非常直接：给模型看大量正确的示例，让它学会模仿。就像培养一名新员工，前期让他看几百份填好的工单，他自然就学会了&amp;quot;遇到这类问题该怎么写工单、该走哪个流程&amp;quot;。&lt;/p&gt;
&lt;p&gt;一条完整的训练样本包含所有角色的消息：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;工具定义&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="err"&gt;模型从这里&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;认识&amp;#34;&lt;/span&gt;&lt;span class="err"&gt;工具&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;北京今天天气怎么样？&amp;#34;&lt;/span&gt; &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="err"&gt;用户提问&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Assistant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tool_calls&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="err"&gt;关键！结构化&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="err"&gt;，不是自然语言&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;get_weather&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;arguments&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;北京&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}}]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;晴，15°C，东北风3级&amp;#34;&lt;/span&gt; &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="err"&gt;模拟工具返回&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Assistant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;北京今天天气晴朗...&amp;#34;&lt;/span&gt; &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="err"&gt;最终自然语言回答&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;模型在几十万甚至上百万条这样的样本上反复训练，通过反向传播（backpropagation）学习：当模型输出的内容偏离正确 JSON 时，损失函数产生惩罚信号，梯度往回传，调整参数权重，让下次输出更接近正确格式。&lt;/p&gt;
&lt;h3 id="23-训练数据需要覆盖的五类场景"&gt;2.3 训练数据需要覆盖的五类场景
&lt;/h3&gt;&lt;p&gt;训练数据的多样性直接决定了 Function Call 能力的上限，不能只有&amp;quot;正常调一个工具&amp;quot;这一种情况。好的训练数据至少要覆盖五类场景：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;缺失的后果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;单工具调用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;最基础的入门场景&lt;/td&gt;
&lt;td&gt;模型连基础调用都不会&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;多工具并行调用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一次输出多个 tool_calls&lt;/td&gt;
&lt;td&gt;模型不知道可以并行，傻乎乎串行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;工具调用失败后重试&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;API 超时、参数错误等情况&lt;/td&gt;
&lt;td&gt;模型遇到错误直接崩掉或傻傻重复&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;不需要工具直接回答&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;1+1等于几&amp;quot;这类问题&lt;/td&gt;
&lt;td&gt;模型形成&amp;quot;遇到问题就调工具&amp;quot;的惯性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;多轮对话中的工具调用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;引用历史上下文中的工具结果&lt;/td&gt;
&lt;td&gt;模型无视历史重新调用&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="24-sft-的短板会了但不知道该不该调"&gt;2.4 SFT 的短板：会了，但不知道&amp;quot;该不该调&amp;rdquo;
&lt;/h3&gt;&lt;p&gt;SFT 让模型学会了&amp;quot;调工具&amp;quot;这个动作，但它不知道什么时候该调、什么时候不该调。因为 SFT 的训练样本里&amp;quot;该调的场景&amp;quot;占了绝大多数（毕竟我们就是要教它调工具），模型在模仿的过程中会过拟合这种&amp;quot;积极调用&amp;quot;的倾向，没看过足够多的&amp;quot;不该调&amp;quot;反例。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;SFT 之后的模型也有类似的毛病：可能对简单问题也尝试调工具，或者遇到工具调用失败时不知道该怎么处理，行为边界感很弱。&amp;rdquo;&lt;/p&gt;
&lt;h3 id="25-第二阶段rlhf用反馈建立边界感"&gt;2.5 第二阶段：RLHF，用反馈建立边界感
&lt;/h3&gt;&lt;p&gt;RLHF（Reinforcement Learning from Human Feedback，人类反馈强化学习）的流程分四步：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 1.生成多样回答 │───→│ 2.人类打分排序 │───→│ 3.训练奖励模型│───→│ 4.强化学习优化│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ (覆盖各种情况) │ │ (哪种回答更好) │ │ (学会打分的RM)│ │ (PPO调主模型) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;生成多样回答&lt;/strong&gt;：对同一个问题，让模型生成几种不同的处理方式——有的调了工具、有的直接回答、有的参数填错了，故意覆盖各种情况。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人类打分&lt;/strong&gt;：标注员评判哪种回答更合理。&amp;ldquo;1+1 等于几&amp;quot;直接回答最好，&amp;ldquo;北京天气怎么样&amp;quot;调工具才对。这批打分数据记录了人类的判断偏好。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;训练奖励模型（RM）&lt;/strong&gt;：用这批打分数据单独训练一个小模型，专门负责打分。它不回答问题，只判断&amp;quot;这个回答人类会喜欢吗&amp;rdquo;——相当于一个&amp;quot;会打分的裁判&amp;rdquo;。人类的判断被&amp;quot;蒸馏&amp;quot;进了这个裁判。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;强化学习优化主模型&lt;/strong&gt;：拿奖励模型的打分，通过 PPO 等算法持续调整主模型参数，让它越来越倾向于产出&amp;quot;高分回答&amp;quot;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="26-为什么偏偏是-ppo"&gt;2.6 为什么偏偏是 PPO
&lt;/h3&gt;&lt;p&gt;强化学习算法那么多，选 PPO 有两个务实的理由：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;相对稳定&lt;/strong&gt;：训练过程不容易崩。传统策略梯度算法很容易因为单步更新太大把模型直接调废。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内置 KL 散度约束&lt;/strong&gt;：强迫新模型和旧模型的输出分布不要差得太远，避免&amp;quot;为了讨好奖励模型，模型把自己训成只会重复几句套话的怪胎&amp;quot;这种退化情况。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;RLHF 本质上要让模型在&amp;quot;追求高奖励&amp;quot;和&amp;quot;保持语言能力&amp;quot;之间走钢丝，PPO 在这个平衡上是目前公认好用的工具。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RLAIF&lt;/strong&gt;（Reinforcement Learning from AI Feedback）是 RLHF 的变体，用更强的 AI 模型（比如 GPT-4）代替人类标注员打分，成本能低 10-100 倍。但代价是&amp;quot;AI 的偏见会传递&amp;quot;——如果打分的 AI 本身对某些场景判断有偏差，这些偏差也会被学进去。现在业界很多模型训练都在混用 RLHF 和 RLAIF，关键数据用人工保质量，量大的地方用 AI 提效率。&lt;/p&gt;
&lt;h3 id="27-两个阶段各司其职"&gt;2.7 两个阶段各司其职
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; SFT RLHF
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;#34;会不会调&amp;#34; &amp;#34;该不该调&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;(教会格式) (建立边界感)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──────────┬─────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 训练好的 Function Call 能力
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;知道怎么调，也知道什么时候该调&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;只有 SFT 而没有 RLHF 的模型，可能遇到什么问题都冲动地调工具；反过来，只有 RLHF 而没有 SFT，模型连工具调用的格式都输不出来，奖励信号根本没地方发力。两个阶段配合起来，才能训练出完整的工具使用能力。&lt;/p&gt;
&lt;h3 id="本章实践要点-1"&gt;本章实践要点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;预训练学不会工具调用&lt;/strong&gt;：不要指望参数量够大就自然涌现，必须做专项微调。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;训练数据要覆盖五类场景&lt;/strong&gt;：缺哪个场景就会在哪个场景翻车，特别是&amp;quot;不需要工具直接回答&amp;quot;这一类经常被忽略。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据来源注意幻觉传递&lt;/strong&gt;：用强模型自动生成训练数据时（Self-Instruct / Distillation），必须人工抽查质量，否则等于在教模型学错误答案。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RLHF 的奖励模型质量是天花板&lt;/strong&gt;：人类标注员标准不一致，奖励模型就会学到歪的打分标准。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="第三章mcp-协议"&gt;第三章：MCP 协议
&lt;/h2&gt;&lt;h3 id="31-nm-问题没有-mcp-之前接工具有多麻烦"&gt;3.1 N×M 问题：没有 MCP 之前，接工具有多麻烦
&lt;/h3&gt;&lt;p&gt;想象你要给 Claude 接入 GitHub 工具。你得手写 GitHub API 的调用代码、处理认证（OAuth token 怎么传）、处理各种返回格式、把 API 响应转成模型能理解的格式……好不容易接好了。结果过了两个月 Claude 升了个版，接口有变化，对接代码得改。更麻烦的是，你同时接了十个工具，每个工具都有自己的一套对接代码。现在产品方说这套工具也要给 Cursor 用——不好意思，重写一遍，因为 Cursor 和 Claude Desktop 的接入方式完全不同。&lt;/p&gt;
&lt;p&gt;这就是 MCP 出现之前 AI 工具生态的真实状态：&lt;strong&gt;碎片化、难复用、强绑定&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;把这个问题抽象出来就是经典的 &lt;strong&gt;N×M 问题&lt;/strong&gt;：N 个 AI 应用要对接 M 个工具，需要维护 N×M 份对接代码。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 没有MCP: N×M 份对接代码 有MCP: N+M 份
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; App1 ──→ ToolA (对接代码) App1 ──┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; App1 ──→ ToolB (对接代码) App2 ──┤ ┌── MCP Server A
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; App1 ──→ ToolC (对接代码) App3 ──┤ ┌──→(ToolA)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ──────┤ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; App2 ──→ ToolA (重写一份) MCP ├─┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; App2 ──→ ToolB (重写一份) Client├─┤ ┌── MCP Server B
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; App2 ──→ ToolC (重写一份) 模块 │ └──→(ToolB)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (N个) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; App3 ──→ ToolA (再重写) ├─┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; App3 ──→ ToolB (再重写) │ └── MCP Server C
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; App3 ──→ ToolC (再重写) (ToolC)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; = N×M 份代码, 改一个工具改 N 处 = N+M 份代码, 各自独立维护
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;MCP（Model Context Protocol，模型上下文协议）的思路是用 USB 接口来类比：在 USB 标准出现之前，鼠标用一个接口、键盘用另一个、打印机又是另一个，换台电脑就愁接口不兼容。USB 出现之后，所有外设统一接口，设备厂商只需要做一次适配，全球所有 USB 电脑都能用。MCP 做的是同一件事：为&amp;quot;AI 接工具&amp;quot;这件事定一套统一的协议标准。&lt;/p&gt;
&lt;h3 id="32-client-server-架构与三个角色"&gt;3.2 Client-Server 架构与三个角色
&lt;/h3&gt;&lt;p&gt;MCP 采用标准的 Client-Server 架构，但定义了三个角色，不只是两个：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;职责&lt;/th&gt;
&lt;th&gt;比喻&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Host&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI 应用本身（如 Claude Desktop），启动和管理所有 Client，控制连哪些 Server&lt;/td&gt;
&lt;td&gt;公司&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Client&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Host 内部的连接模块，一个 Client 对应一个 Server 连接。负责初始化连接、能力发现、转发调用请求&lt;/td&gt;
&lt;td&gt;驻场联络员&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;工具提供方实现的独立进程，对外暴露 Tools/Resources/Prompts&lt;/td&gt;
&lt;td&gt;外部供应商&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;关键设计：&lt;strong&gt;一个 Host 可以同时连多个 Server&lt;/strong&gt;。你把文件系统 Server + GitHub Server + PostgreSQL Server 都接上，模型就同时拥有了操作本地文件、读写代码仓库、查询数据库这三套工具能力，而你不需要写任何对接代码，只需要在配置文件里加几行 JSON。&lt;/p&gt;
&lt;p&gt;Server 完全不关心上面是哪个 Host 在用它，只需要按 MCP 协议响应 Client 的请求就行。这也是 MCP 的核心价值：Server 写一次，任何支持 MCP 的 Host 都能直接用。&lt;/p&gt;
&lt;h3 id="33-三类核心能力tools--resources--prompts"&gt;3.3 三类核心能力：Tools / Resources / Prompts
&lt;/h3&gt;&lt;p&gt;MCP Server 可以向 Client 暴露三类能力，各有各的定位：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;能力&lt;/th&gt;
&lt;th&gt;本质&lt;/th&gt;
&lt;th&gt;副作用&lt;/th&gt;
&lt;th&gt;授权要求&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tools（工具）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;有副作用的操作，执行后改变外部状态&lt;/td&gt;
&lt;td&gt;有（创建文件、提交代码、发消息、调API）&lt;/td&gt;
&lt;td&gt;通常需要用户授权确认&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Resources（资源）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;只读数据，不改变任何东西&lt;/td&gt;
&lt;td&gt;无（读取日志、查数据库记录、获取文档）&lt;/td&gt;
&lt;td&gt;可更宽松暴露&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prompts（提示模板）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;预定义的提示词模板，带参数占位符&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;可共享复用&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;三者的本质区别可以这样记：&lt;strong&gt;Tools 改变世界，Resources 观察世界，Prompts 结构化表达&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Resources 和 Tools 最本质的区别是一个字：&amp;ldquo;只读&amp;rdquo;。你可以把 Resources 理解成&amp;quot;工具的资料室&amp;quot;，模型可以进去查资料，但不能修改里面的东西。正因为只读、无副作用，Resources 可以更宽松地暴露给模型，不需要像 Tools 那样谨慎授权。&lt;/p&gt;
&lt;h3 id="34-json-rpc-20底层消息格式"&gt;3.4 JSON-RPC 2.0：底层消息格式
&lt;/h3&gt;&lt;p&gt;Client 和 Server 之间的消息格式统一用 JSON-RPC 2.0。每条消息是一个 JSON 对象，格式固定：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Client 向 Server 查询工具列表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tools/list&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Server 返回工具列表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;read_file&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Client 请求调用某个工具
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;jsonrpc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tools/call&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;read_file&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;arguments&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/tmp/log.txt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;用 JSON 而不是二进制格式，好处是易读、易调试、语言无关，不管 Server 是 Python 写的还是 TypeScript 写的，消息格式是一样的。MCP 用 JSON-RPC 2.0（相比 1.0 加了批量请求、通知消息等功能）。&lt;/p&gt;
&lt;h3 id="35-两种传输方式"&gt;3.5 两种传输方式
&lt;/h3&gt;&lt;p&gt;消息格式定了，怎么传呢？MCP 支持两种传输方式：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────┐ ┌─────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ stdio (本地) │ │ Streamable HTTP (远程) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────┤ ├─────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Server 作为子进程 │ │ Server 作为 HTTP 服务 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 通过 OS 管道通信 │ │ Client 通过网络连接 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ✓ 延迟极低 │ │ ✓ 多Client共享一个Server │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ✓ 不开端口,无安全问题 │ │ ✓ 支持跨机器访问 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ✓ 生命周期自动管理 │ │ ✗ 有网络开销 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ✗ 仅限本地 │ │ ✗ 需处理认证/重连 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────┘ └─────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;stdio（标准输入输出）&lt;/strong&gt;：Server 作为本地子进程运行，Host 通过操作系统的管道和它通信，Server 从 stdin 读请求、把结果写到 stdout。整个过程不经过网卡、不经过 TCP/IP 协议栈，数据在 RAM 里走了一趟就到了，延迟天然比网络请求低得多。Claude Desktop 接本地 MCP Server 走的就是这种方式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Streamable HTTP&lt;/strong&gt;：Server 作为 HTTP 服务独立部署，Client 通过网络连接访问。用单个 HTTP 端点（通常是 &lt;code&gt;/mcp&lt;/code&gt;）同时处理请求和响应：Client 用 POST 发请求，Server 根据情况灵活返回——短请求直接回普通 JSON，长请求则把 HTTP 响应升级为 SSE 流持续推送中间结果。&lt;/p&gt;
&lt;p&gt;这里有一个很重要的设计点：&lt;strong&gt;消息格式（JSON-RPC 2.0）和传输方式（stdio / Streamable HTTP）是解耦的&lt;/strong&gt;。同一套 JSON-RPC 消息可以跑在任意传输层上，切换传输方式不影响上层的工具调用逻辑。这让 MCP Server 既可以轻量地作为本地进程运行，也可以作为正式的微服务部署。&lt;/p&gt;
&lt;h3 id="36-sse-双端点到-streamable-http-的演进"&gt;3.6 SSE 双端点到 Streamable HTTP 的演进
&lt;/h3&gt;&lt;p&gt;MCP 早期版本（2024-11-05 规范）的远程传输方案叫&amp;quot;HTTP + SSE&amp;quot;，是双端点结构：一个 GET 端点开 SSE 长连接接收 Server 推送，一个 POST 端点用来发请求。这套方案在 2025 年 3 月的规范更新里被改成了单端点的 &lt;strong&gt;Streamable HTTP&lt;/strong&gt;（老的 HTTP+SSE 被标记为 deprecated，但保留向后兼容）。&lt;/p&gt;
&lt;p&gt;为什么要替换？因为双端点有一个小尴尬：同一个对话被拆成了两条通道。Client POST 了一条消息之后网络突然断了，那条消息到底被处理了没、SSE 流会不会推回结果，Client 没有一个简单的办法判断，出问题时排查链路很长。&lt;/p&gt;
&lt;p&gt;Streamable HTTP 把两条通道合并成一个端点，架构更简洁，对负载均衡器和 serverless 环境都更友好。&lt;strong&gt;注意：Streamable HTTP 并没有抛弃 SSE&lt;/strong&gt;，流式推送的部分底层还是 SSE（&lt;code&gt;Content-Type: text/event-stream&lt;/code&gt;），只是把端点从两个合成一个。&lt;/p&gt;
&lt;h3 id="37-生态发展快的原因"&gt;3.7 生态发展快的原因
&lt;/h3&gt;&lt;p&gt;MCP 是 Anthropic 在 2024 年底发布的，发布后发展速度很快，主要有两个原因：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;极低的实现门槛&lt;/strong&gt;：Anthropic 开源了协议规范和多语言 SDK（Python、TypeScript 都有），写一个最简单的 MCP Server 不到 30 行代码。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;头部工具第一时间跟进&lt;/strong&gt;：GitHub、Slack、PostgreSQL、Puppeteer、Google Maps 等高频工具都有了官方或社区维护的 MCP Server，接一个新工具就是配置文件里加几行 JSON，零代码。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="本章实践要点-2"&gt;本章实践要点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MCP 是协议不是框架&lt;/strong&gt;：它解决的是&amp;quot;工具怎么标准化接入&amp;quot;，不是&amp;quot;模型怎么输出调用请求&amp;quot;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Host ≠ Client&lt;/strong&gt;：Host 是宿主应用本身，Client 是 Host 内部负责和 Server 通信的模块，一个 Host 可以连多个 Server。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;三类能力职责分明&lt;/strong&gt;：Tools 有副作用需授权，Resources 只读无副作用，Prompts 是可复用模板。不要把只读数据和有副作用的操作混为一谈。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;消息格式和传输方式解耦&lt;/strong&gt;：JSON-RPC 2.0 定义消息长什么样，stdio/Streamable HTTP 定义消息怎么传，两者互不耦合。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;新项目用 Streamable HTTP&lt;/strong&gt;：HTTP+SSE 双端点方案已 deprecated，仍向后兼容但不推荐新项目使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="第四章mcp-vs-function-calling"&gt;第四章：MCP vs Function Calling
&lt;/h2&gt;&lt;h3 id="41-语言层-vs-工具箱层"&gt;4.1 语言层 vs 工具箱层
&lt;/h3&gt;&lt;p&gt;很多人第一次看到 MCP 会有一个直觉困惑：Function Calling 不是已经能调工具了吗，为什么还要再搞一个协议？这个困惑的根源，是把&amp;quot;能调工具&amp;quot;和&amp;quot;管好工具&amp;quot;混在一起了。&lt;/p&gt;
&lt;p&gt;有一个很好的类比：HTTP 协议出来之后，我们已经能在网络上传数据了，为什么还需要 REST API 规范？因为 HTTP 解决的是&amp;quot;怎么传&amp;quot;（一次请求长什么样、用什么方法、怎么编码），REST 解决的是&amp;quot;怎么组织和管理&amp;quot;（资源怎么命名、端点怎么设计、状态怎么表达、多个服务之间怎么复用同一套约定）。&lt;/p&gt;
&lt;p&gt;Function Calling 和 MCP 也是同样的关系：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;Function Calling&lt;/th&gt;
&lt;th&gt;MCP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;解决什么&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;模型怎么输出调用请求&lt;/td&gt;
&lt;td&gt;工具怎么标准化接入&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;层次&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;调用语言（格式）&lt;/td&gt;
&lt;td&gt;工具生态（规范+管理）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;类比&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTTP 请求格式&lt;/td&gt;
&lt;td&gt;REST API 规范 + 服务注册发现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;工具管理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无，每次手动写 schema&lt;/td&gt;
&lt;td&gt;有，自动发现、注册&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;跨项目复用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无，换个项目重写&lt;/td&gt;
&lt;td&gt;有，一次实现到处复用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;跨模型兼容&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无，各家格式不同&lt;/td&gt;
&lt;td&gt;有，协议统一&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="42-function-calling-的痛点每次都是一次性的"&gt;4.2 Function Calling 的痛点：每次都是一次性的
&lt;/h3&gt;&lt;p&gt;&amp;ldquo;每次手动&amp;quot;到底有多痛？假设你团队里有 5 个应用，每个应用要接 8 个工具，也就是 40 份工具对接代码在维护。某天 GitHub API 的某个字段变了，你要在 5 个地方同步改，只要其中一个忘了，那个应用在凌晨报警。再假设你要从 Claude 迁到 GPT-4，这 40 份代码里的 Function Calling 格式全要重新适配一遍。&lt;/p&gt;
&lt;p&gt;同一个工具，换个项目就要重新对接一遍，每次都是一次性的手工活。这就是 Function Calling 解决不了的核心问题：&lt;strong&gt;工具的管理、复用和跨平台兼容&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="43-最关键的联系mcp-底层依然靠-function-calling-驱动"&gt;4.3 最关键的联系：MCP 底层依然靠 Function Calling 驱动
&lt;/h3&gt;&lt;p&gt;这是很多人没想清楚的一点：&lt;strong&gt;MCP 不是 Function Calling 的替代品，而是建立在 Function Calling 之上的&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;当 MCP Client 连上一个 Server 之后，会自动向 Server 拉取所有工具的定义（调用 &lt;code&gt;list_tools&lt;/code&gt; 接口），然后把这些定义&lt;strong&gt;转换成模型原生的 Function Calling 格式&lt;/strong&gt;传给模型。模型依然通过输出 &lt;code&gt;tool_calls&lt;/code&gt; 来表达&amp;quot;我要调哪个工具&amp;rdquo;，MCP Client 再把这个请求路由到对应的 Server 去执行，拿到结果后以 tool 消息的形式喂回对话。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;模型视角&lt;/span&gt; &lt;span class="n"&gt;MCP&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;宿主程序层&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;MCP&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt; &lt;span class="err"&gt;───────&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list_tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;转成&lt;/span&gt;&lt;span class="n"&gt;FC格式&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;←───&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;──&lt;/span&gt; &lt;span class="n"&gt;tool_calls&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt; &lt;span class="err"&gt;──→&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;路由到对应&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;─────────→│&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;执行&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="k"&gt;tool&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="err"&gt;────────&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool消息喂回&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;←────────────&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;返回&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;模型完全感知不到&lt;/span&gt;&lt;span class="n"&gt;MCP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;所有&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;魔法&amp;#34;&lt;/span&gt;&lt;span class="err"&gt;都在这一层&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;从&lt;strong&gt;模型的视角&lt;/strong&gt;来看，它完全感知不到 MCP 的存在，它以为自己只是在做普通的 Function Calling，根本不知道背后有一套 Server 在运行。MCP 的所有&amp;quot;魔法&amp;quot;都发生在宿主程序层：工具的自动发现、schema 的格式转换、调用请求的路由、执行结果的返回，全都在这一层默默完成。&lt;/p&gt;
&lt;p&gt;这也意味着：&lt;strong&gt;如果模型本身不支持 Function Calling，MCP 就完全没办法用&lt;/strong&gt;，因为这个&amp;quot;翻译层&amp;quot;失效了。&lt;/p&gt;
&lt;h3 id="44-自己写一个-mcp-server-有多简单"&gt;4.4 自己写一个 MCP Server 有多简单
&lt;/h3&gt;&lt;p&gt;以 Python SDK 为例，核心就三步：用 &lt;code&gt;@app.list_tools()&lt;/code&gt; 装饰器声明工具、用 &lt;code&gt;@app.call_tool()&lt;/code&gt; 装饰器实现执行逻辑、用 stdio 方式运行。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;mcp.server&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;mcp.server.stdio&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;stdio_server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;mcp.types&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TextContent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;calculator&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 定义工具列表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@app.list_tools&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_tools&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;add_numbers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;计算两个数字的和&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;inputSchema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;number&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;第一个数字&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;number&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;第二个数字&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;required&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 实现工具执行逻辑&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@app.call_tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TextContent&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;add_numbers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TextContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;计算结果: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TextContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;未知工具: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 启动 Server (stdio模式)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;stdio_server&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;read_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;read_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_initialization_options&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后在 &lt;code&gt;claude_desktop_config.json&lt;/code&gt; 里加几行配置：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mcpServers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;calculator&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;python&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/path/to/your/calculator_server.py&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;配好之后重启 Claude Desktop，直接输入&amp;quot;帮我算一下 25 加 17 等于多少&amp;quot;，Claude 就会自动调用你写的 &lt;code&gt;add_numbers&lt;/code&gt; 工具。整个过程你只写了工具逻辑本身，所有的通信、发现、调用路由都由 MCP 框架搞定了。&lt;/p&gt;
&lt;h3 id="45-选型判断框架"&gt;4.5 选型判断框架
&lt;/h3&gt;&lt;p&gt;碰到&amp;quot;用 Function Calling 还是 MCP&amp;quot;这个选择题，按几个问题依次过一遍：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 开始
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌───────────▼───────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 社区有现成MCP Server? │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └───┬───────────────┬───┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 是│ 否│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 直接用MCP │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌────▼───────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 工具需要跨项目 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ /跨团队复用? │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──┬──────────┬──┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 是│ 否│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 用MCP │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌────▼────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 工具规模起来了? │ (数量+复杂度+团队规模+变更频率)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──┬───────┬──┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 是│ 否│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 用MCP │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌───▼──────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 做正式 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ Agent系统?│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─┬──────┬─┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 是│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 用MCP │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌──▼──────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │受限环境? │ (Serverless不能起子进程)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──┬──────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 是│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 用Function Calling
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;总结成一句话：&lt;strong&gt;&amp;ldquo;只用自己、只用一次、不需要复用&amp;quot;才适合 Function Calling，其他情况优先考虑 MCP&lt;/strong&gt;。两者不是竞争关系，MCP 底层本来就是靠 Function Calling 驱动的，选哪个取决于你的工程需求。&lt;/p&gt;
&lt;h3 id="本章实践要点-3"&gt;本章实践要点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不是替代关系&lt;/strong&gt;：MCP 底层靠 Function Calling 驱动，模型感知不到 MCP 的存在。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;选型看多维度&lt;/strong&gt;：社区现成 Server、复用需求、工具规模、Agent 系统、部署环境，不能只看一个指标。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内嵌 vs 独立&lt;/strong&gt;：Function Calling 的工具&amp;quot;内嵌&amp;quot;在应用代码里，MCP 的工具&amp;quot;独立&amp;quot;为标准进程。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;受限环境退回 FC&lt;/strong&gt;：某些 Serverless 平台不允许启动子进程，stdio 模式的 MCP Server 没法用。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="第五章skill任务流程知识化"&gt;第五章：Skill——任务流程知识化
&lt;/h2&gt;&lt;h3 id="51-从重复贴-prompt的痛点说起"&gt;5.1 从&amp;quot;重复贴 prompt&amp;quot;的痛点说起
&lt;/h3&gt;&lt;p&gt;你一定遇到过这种情况：每次让 AI 帮你做代码审查，你都要贴一大段指令——&amp;ldquo;检查这几类问题、用这种格式输出、重点关注安全漏洞&amp;rdquo;。第一次贴还好，第十次你就开始烦了，每次新对话都要从头贴一遍，漏掉某个细节就会导致输出质量不稳定。&lt;/p&gt;
&lt;p&gt;这还只是一个人的情况。如果是团队协作呢？十个人做代码审查，每个人贴的 prompt 都不一样，有人关注安全，有人关注性能，审查标准完全没法统一。你可能想到把 prompt 写到共享文档里让大家复制，但这本质上还是靠人工维护和执行，版本一多就容易乱。&lt;/p&gt;
&lt;p&gt;Skill 要解决的就是这个问题：把那些你反复在用的指令、流程、模板，打包成一个标准化的模块，&lt;strong&gt;Agent 自己知道什么时候该用它、怎么用它&lt;/strong&gt;，不再依赖你手动复制粘贴。&lt;/p&gt;
&lt;h3 id="52-skill-的结构"&gt;5.2 Skill 的结构
&lt;/h3&gt;&lt;p&gt;一个 Skill 说白了就是一个文件夹，里面最核心的是一份 &lt;code&gt;SKILL.md&lt;/code&gt; 文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;code-review/ # Skill 文件夹，名字就是标识
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── SKILL.md # 核心指令文件（必须有）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── scripts/ # 可选：可执行的脚本
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── check_security.py # 比如一个安全检查脚本
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── references/ # 可选：参考文档
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── review_standards.md # 比如团队的审查标准文档
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── assets/ # 可选：模板、资源文件
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── report_template.md # 比如审查报告的输出模板
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;SKILL.md&lt;/code&gt; 的内容分两部分：顶部是 YAML 格式的元数据（frontmatter），声明名字和一句话描述；下面是 Markdown 正文，写具体的指令和步骤：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;name: code-review
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;description: &amp;#34;对代码进行全面审查，检查 bug、安全漏洞和性能问题，输出结构化审查报告&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# 代码审查 Skill
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## 指令
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### 第一步：理解代码上下文
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;阅读提交的代码，理解它的功能和所属模块，确认修改范围。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### 第二步：逐项检查
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;按以下维度逐一检查：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;1.&lt;/span&gt; 功能正确性：逻辑是否有 bug，边界条件是否处理了
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;2.&lt;/span&gt; 安全性：是否有注入、XSS、权限绕过等漏洞
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;3.&lt;/span&gt; 性能：是否有 N+1 查询、不必要的循环、内存泄漏风险
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### 第三步：输出报告
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;&lt;/span&gt;使用 assets/report_template.md 的模板格式，输出结构化的审查报告。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="53-渐进式加载skill-最聪明的设计"&gt;5.3 渐进式加载：Skill 最聪明的设计
&lt;/h3&gt;&lt;p&gt;Skill 最让人眼前一亮的设计不是&amp;quot;能打包&amp;rdquo;，而是它的加载方式——&lt;strong&gt;渐进式加载（Progressive Disclosure）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;假设你有 20 个 Skill，每个平均 2000 token，全部加载就是 4 万 token 打底，吃掉了 20 万上下文窗口的五分之一，而大部分在当前任务里根本用不上。Skill 用三层机制解决这个问题：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌──────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 第1层：只看简历 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 启动时只加载 name + description │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 每个 Skill ~30-50 token │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ &amp;#34;我手上有哪些能力可以用&amp;#34; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├──────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 第2层：翻开详细资料 (按需) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ Agent判断某Skill与当前任务相关时 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 才加载 SKILL.md 正文 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 不相关的Skill始终不加载 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├──────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 第3层：需要时再取 (用到才取) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 执行中指令提到&amp;#34;使用assets/xxx模板&amp;#34;时 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 才读取那个模板文件 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 参考文档、脚本同理 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个设计用一个类比就很好理解：Skill 就像公司给新员工准备的入职手册。你入职第一天不会把整本手册从头到尾看完，而是先扫一眼目录，知道里面有&amp;quot;报销流程&amp;quot;&amp;ldquo;请假制度&amp;quot;&amp;ldquo;代码规范&amp;quot;这些章节就行了。等你真的要报销了，再翻开&amp;quot;报销流程&amp;quot;那一章仔细看。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;为什么这个设计这么重要？&lt;/strong&gt; 因为 context window 是 Agent 最宝贵的资源。如果把所有 Skill 的全部内容一股脑塞进去，真正有用的用户任务信息反而会被淹没，Agent 的注意力被分散，输出质量反而下降。&lt;/p&gt;
&lt;h3 id="54-skill-与-mcp-的关系操作手册层"&gt;5.4 Skill 与 MCP 的关系：操作手册层
&lt;/h3&gt;&lt;p&gt;Skill 和 MCP 处于完全不同的层次，用一个类比就能讲清楚：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;概念&lt;/th&gt;
&lt;th&gt;比喻&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP / Tool&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;公司给员工配的电脑、软件和数据库权限&lt;/td&gt;
&lt;td&gt;提供能力（能做事）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Skill&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;操作手册和 SOP 流程&lt;/td&gt;
&lt;td&gt;提供知识和流程（知道怎么做）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prompt&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;口头跟员工说的一句话指令&lt;/td&gt;
&lt;td&gt;一次性、临时&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;MCP 给 Agent 提供的是工具和数据的访问能力，Skill 教 Agent 拿到这些工具之后该怎么用。&lt;strong&gt;一个是&amp;quot;能力&amp;rdquo;，一个是&amp;quot;知识和流程&amp;rdquo;&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;那 Slash Command 呢？它也是把指令保存下来复用，但必须由你手动触发（输入 &lt;code&gt;/code-review&lt;/code&gt;）。而 Skill 可以被 Agent &lt;strong&gt;自动发现和调用&lt;/strong&gt;——Agent 看到你的任务后，自己判断&amp;quot;这个任务需要用 code-review Skill&amp;quot;，然后主动去加载和执行。&lt;/p&gt;
&lt;h3 id="55-skill-和-mcp-怎么配合工作"&gt;5.5 Skill 和 MCP 怎么配合工作
&lt;/h3&gt;&lt;p&gt;用一个代码审查场景走一遍：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;用户：&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;帮我审查这次提交的代码&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;┌─────────────────┐&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;Skill层起作用&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;Agent扫描Skill列表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;发现&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;review匹配&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;加载&lt;/span&gt;&lt;span class="n"&gt;SKILL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;读取执行流程&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;第&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;步&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;读代码&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;第&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;步&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;安全检查&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;第&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;步&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;输出报告&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;└────────┬────────┘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;┌─────────────────┐&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;MCP层起作用&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;执行第&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;步&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;读代码&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;调用文件系统&lt;/span&gt;&lt;span class="n"&gt;MCP&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mcp_&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;read_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;src/auth.py&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="k"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;read_ │&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;, {...}) │&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;└────────┬────────┘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;┌─────────────────┐&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;Skill自带脚本&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;执行第&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;步&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;安全检查&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;加载&lt;/span&gt;&lt;span class="n"&gt;scripts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;check_security&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;运行脚本&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Skill不只有文字&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;还能带脚本&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;└────────┬────────┘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;│&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;▼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;┌─────────────────┐&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;Skill自带模板&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;执行第&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;步&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;输出报告&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;加载&lt;/span&gt;&lt;span class="n"&gt;assets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;report_template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;按模板格式输出&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;整理成结构化报告&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;└─────────────────┘&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;分工非常清晰：&lt;strong&gt;Skill 扮演&amp;quot;编排者&amp;quot;&lt;/strong&gt;，定义了做什么、按什么顺序做、用什么标准做；&lt;strong&gt;MCP 扮演&amp;quot;执行者&amp;quot;&lt;/strong&gt;，提供了每一步需要调用的具体工具。缺了 Skill，Agent 拿着一堆工具不知道该什么时候用；缺了 MCP，Skill 再详细的流程也只是纸上谈兵。&lt;/p&gt;
&lt;h3 id="本章实践要点-4"&gt;本章实践要点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Skill 不是 prompt&lt;/strong&gt;：它是一个包含指令、脚本、模板的可复用能力模块，Agent 可以自动发现和按需加载。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;渐进式加载是核心设计&lt;/strong&gt;：三层加载机制（只读元数据 → 按需加载指令 → 用到时才取资源）体现的是&amp;quot;context 工程&amp;quot;思维。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skill 和 MCP 互补&lt;/strong&gt;：MCP 提供工具和数据访问，Skill 提供用这些工具完成任务的知识和流程。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skill 粒度比 MCP 粗得多&lt;/strong&gt;：MCP 粒度是单个函数调用，Skill 粒度是完整工作流程，内部可能涉及好几个步骤、调用好几个工具。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="第六章fc--mcp--skill-三层架构全景"&gt;第六章：FC / MCP / Skill 三层架构全景
&lt;/h2&gt;&lt;h3 id="61-为什么会有三个概念"&gt;6.1 为什么会有三个概念
&lt;/h3&gt;&lt;p&gt;这三个概念放在一起确实容易让人迷惑，但它们各自解决的是完全不同层次的问题，是&lt;strong&gt;三层架构，不是三个竞争方案&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;从时间线来看更清楚：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Function Calling（2023）&lt;/strong&gt;：最先出现，核心问题是&amp;quot;模型只会生成文本，怎么让它触发外部调用&amp;quot;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MCP（2024 底）&lt;/strong&gt;：Function Calling 普及后，痛点变成&amp;quot;每个应用都要自己写代码对接各种工具，重复劳动太多&amp;quot;。MCP 把工具接入标准化。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skill（2025 年 10 月）&lt;/strong&gt;：工具有了、接入也标准化了，又冒出新问题&amp;quot;Agent 有了一堆工具，但不知道该按什么流程用&amp;quot;。Skill 解决知识和流程复用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;三者的出现背景不同，自然解决的是不同层次的东西。&lt;/p&gt;
&lt;h3 id="62-三层架构全景图"&gt;6.2 三层架构全景图
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;╔══════════════════════════════════════════════════════════╗&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;用户任务输入&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;帮我分析最近三个月的销售数据&amp;#34;&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;╠══════════════════════════════════════════════════════════╣&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;┌─&lt;/span&gt; &lt;span class="n"&gt;Skill&lt;/span&gt; &lt;span class="err"&gt;层&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;操作手册&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;─────────────────────────────┐&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;Agent扫描Skill列表&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;匹配&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;数据分析报告&amp;#34;&lt;/span&gt;&lt;span class="n"&gt;Skill&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;加载&lt;/span&gt;&lt;span class="n"&gt;SKILL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;第&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;步&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;从数据库取数据&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;第&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;步&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;用&lt;/span&gt;&lt;span class="n"&gt;Python做趋势分析&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;第&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;步&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;按模板写报告&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;定义流程&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;做什么、什么顺序、什么标准&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;└───────────────────────┬──────────────────────────┘&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;每步需要调工具时&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;┌───────────────────────▼──────────────────────────┐&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;MCP&lt;/span&gt; &lt;span class="err"&gt;层&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;工具箱&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;MCP&lt;/span&gt; &lt;span class="n"&gt;Client自动发现工具&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;•&lt;/span&gt; &lt;span class="n"&gt;query_database&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;数据库&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;•&lt;/span&gt; &lt;span class="n"&gt;run_python&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Python执行器Server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;提供工具&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;一次实现&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;到处复用&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;自动发现&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;└───────────────────────┬──────────────────────────┘&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;模型触发调用时&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;┌───────────────────────▼──────────────────────────┐&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;Function&lt;/span&gt; &lt;span class="n"&gt;Calling&lt;/span&gt; &lt;span class="err"&gt;层&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;调用语言&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;模型输出&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query_database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SELECT...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;模型输出&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run_python&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;df.groupby...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;模型决策&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;调哪个函数、参数是什么&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;└───────────────────────────────────────────────────┘&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;╠══════════════════════════════════════════════════════════╣&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;最终结构化报告输出&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;╚══════════════════════════════════════════════════════════╝&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="63-用做菜来类比"&gt;6.3 用做菜来类比
&lt;/h3&gt;&lt;p&gt;用做菜来类比就很好理解三层的关系：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;层&lt;/th&gt;
&lt;th&gt;类比&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Function Calling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;你的&amp;quot;手&amp;quot;&lt;/td&gt;
&lt;td&gt;能拿刀、能点火、能翻锅，最基础的操作能力&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;你的&amp;quot;厨房&amp;quot;&lt;/td&gt;
&lt;td&gt;里面有各种厨具和食材，刀在抽屉里、调料在架子上，走进去就知道有什么可用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Skill&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;菜谱&amp;rdquo;&lt;/td&gt;
&lt;td&gt;告诉你先热锅凉油、再放姜蒜爆香、然后下主料翻炒、最后调味出锅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;跳过其中一层会怎样？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;没有手（FC）&lt;/strong&gt;：你站在厨房里、拿着菜谱，什么都做不了，连刀都拿不起来。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没有厨房（MCP）&lt;/strong&gt;：就算你有手、有菜谱，家里什么厨具都没有，只能空手对着菜谱发呆。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没有菜谱（Skill）&lt;/strong&gt;：你有手、也有满厨房的厨具，但面对一桌食材不知道先切什么、后炒什么，只能瞎折腾。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;三者缺一不可，各管各的层次。完整的链条是：&lt;strong&gt;Skill（定义流程）→ MCP（提供工具）→ Function Calling（模型触发调用）&lt;/strong&gt;，从上到下三层，每一层都建立在下一层的基础之上。&lt;/p&gt;
&lt;h3 id="64-三层各自谁和谁通信"&gt;6.4 三层各自&amp;quot;谁和谁通信&amp;quot;
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;机制&lt;/th&gt;
&lt;th&gt;发生在&lt;/th&gt;
&lt;th&gt;主语&lt;/th&gt;
&lt;th&gt;粒度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Function Calling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;模型 ↔ 函数&lt;/td&gt;
&lt;td&gt;模型说&amp;quot;我要调这个函数&amp;quot;&lt;/td&gt;
&lt;td&gt;单次调用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI客户端 ↔ 工具服务&lt;/td&gt;
&lt;td&gt;工具服务说&amp;quot;我能提供这些函数&amp;quot;&lt;/td&gt;
&lt;td&gt;原子操作&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Skill&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent ↔ 知识模块&lt;/td&gt;
&lt;td&gt;操作手册说&amp;quot;用这些工具按这个流程做&amp;quot;&lt;/td&gt;
&lt;td&gt;工作流程&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;三句话的主语不一样，说话对象不一样，粒度也不一样，这就是三者的本质差异。&lt;/p&gt;
&lt;h3 id="本章实践要点-5"&gt;本章实践要点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不是三个竞争方案&lt;/strong&gt;：它们是三层架构，从底到顶各司其职。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;层级依赖明确&lt;/strong&gt;：Skill 依赖 MCP 提供工具，MCP 依赖 Function Calling 触发调用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用完整场景串联&lt;/strong&gt;：理解三者的最好方式是把它们放在同一个任务里走一遍——Skill 编排流程，MCP 提供工具，Function Calling 做模型和工具的通信。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="第七章推理模型与工具调用冲突"&gt;第七章：推理模型与工具调用冲突
&lt;/h2&gt;&lt;h3 id="71-范式冲突的本质"&gt;7.1 范式冲突的本质
&lt;/h3&gt;&lt;p&gt;普通模型的工作方式很直接：问题进来，答案出去。推理模型（Reasoning Model）不一样，它在给出最终答案之前，会先生成一大段&amp;quot;内部思考&amp;quot;（thinking tokens），在思考里自言自语地推演、验证、反驳，甚至推翻自己前面的结论重来。代表模型有 OpenAI o1/o3 系列、DeepSeek-R1、Claude 的扩展思考（Extended Thinking）模式。&lt;/p&gt;
&lt;p&gt;工具调用的本质是&amp;quot;中途暂停&amp;quot;：模型生成调用请求 → &lt;strong&gt;停下来等宿主程序执行&lt;/strong&gt; → 拿到结果 → 继续生成。而推理模型的思考链是一次性连续生成的，不能中途打断。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这两种生成范式是根本冲突的。&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 普通模型 + 工具调用 (没问题):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ────生成────[暂停]──执行──[恢复]────生成────
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 可以随时截断再重新启动
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 推理模型 + 工具调用 (冲突!):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ──思考──思考──思考──[???暂停???]──思考──思考──
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 思考链是连续整体, 中途打断=推理上下文全断
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="72-直觉类比写推理过程中途被打断"&gt;7.2 直觉类比：写推理过程中途被打断
&lt;/h3&gt;&lt;p&gt;想象你正在心无旁骛地写一篇复杂的推理论文，脑子里已经建立了一整套逻辑框架，各个论点之间的关系都串起来了，正处于思维最活跃的时刻。突然电话来了，你放下笔去接了 20 分钟电话，再回来坐下——很多细节想不起来了，之前好不容易建立的推理脉络断了，只能重新梳理。&lt;/p&gt;
&lt;p&gt;推理模型的思考链就是这种东西。它是一个依赖完整上下文的连续生成过程，每一步推理都建立在前面所有推理内容的基础上。中途强行打断，之前建立的推理状态会断掉，模型没办法从中间接着想，只能整个重来。&lt;/p&gt;
&lt;h3 id="73-那保存状态再恢复不就行了"&gt;7.3 &amp;ldquo;那保存状态再恢复不就行了？&amp;rdquo;
&lt;/h3&gt;&lt;p&gt;有人可能会问：暂停时把状态保存起来，工具执行完再恢复，不就解决了？&lt;/p&gt;
&lt;p&gt;听起来可行，但实际代价很大。模型推理时的中间状态可以想象成一本&amp;quot;思考草稿本&amp;quot;——技术上叫 &lt;strong&gt;KV Cache&lt;/strong&gt;，是模型缓存注意力计算结果的结构，体积非常庞大。一旦暂停，这本草稿本就得原封不动占着一块 GPU 显存，工具执行要几秒、几十秒，这块显存就一直被占着不能给别的请求用。工具执行完再接着想，显存占用翻倍、吞吐量直接腰斩，整体延迟也大幅上升。对一个需要同时服务成千上万请求的在线推理系统来说，这个代价完全承受不了。&lt;/p&gt;
&lt;p&gt;更难解决的是&lt;strong&gt;一致性问题&lt;/strong&gt;：思考过程中途接入工具结果，等于在模型&amp;quot;想到一半&amp;quot;时改变了输入。模型之前的思路是基于&amp;quot;我还不知道工具结果&amp;quot;建立的，突然工具结果来了，模型需要重新校准，之前的推理链和新来的工具结果可能是矛盾的。&lt;/p&gt;
&lt;h3 id="74-训练目标上的冲突"&gt;7.4 训练目标上的冲突
&lt;/h3&gt;&lt;p&gt;除了生成范式，训练层面也有根本性冲突。推理模型的训练核心是：用强化学习大量奖励&amp;quot;思考链完整且结论正确&amp;quot;的输出，模型越来越倾向于&amp;quot;一直想、想到底&amp;quot;。而 Function Calling 的训练恰好相反，需要模型学会&lt;strong&gt;在合适时机打断自己&lt;/strong&gt;，从推理状态切换出来输出结构化 JSON。&lt;/p&gt;
&lt;p&gt;如果强行把两种训练数据混在一起喂，常见的失败模式有三种：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;模型在思考到一半突然跳出来输出一段奇怪的 JSON，格式还错了，两边都没干好。&lt;/li&gt;
&lt;li&gt;模型彻底偏向一边——要么思考链缩水变浅（变成普通模型），要么干脆不会输出工具调用。&lt;/li&gt;
&lt;li&gt;融合处的推理断裂，工具结果回来之后模型的后续推理和之前的思考链对不上，答非所问。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以早期推理模型宁可先放弃工具调用，也要先把推理能力做扎实。&lt;/p&gt;
&lt;h3 id="75-折中方案interleaved-thinking"&gt;7.5 折中方案：interleaved thinking
&lt;/h3&gt;&lt;p&gt;后续版本找到的工程解法是：&lt;strong&gt;让工具调用发生在思考阶段结束之后&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 折中方案:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ──思考思考思考思考──[思考结束]──[调工具]──[拿结果]──生成答案──
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 思考过程仍然一次性完整生成, 不被打断
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 工具调用发生在&amp;#34;答案生成阶段&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;具体做法是：模型先把整个推理链完整跑完，进入&amp;quot;输出最终答案&amp;quot;阶段时，才触发 Function Calling 流程。这样思考过程仍然是一次性完整生成的，推理质量得以保住。代价是：思考阶段完全感知不到工具结果，模型只能基于自己的已有知识来推理。&lt;/p&gt;
&lt;p&gt;o3 和 Claude Extended Thinking 走的都是这条路。Claude 还进一步推出了 &lt;strong&gt;interleaved thinking（交错思考）&lt;/strong&gt; 模式，允许模型在多次工具调用之间穿插思考，而不是只能在所有思考结束后才调用工具，在一定程度上缓解了&amp;quot;思考阶段感知不到工具结果&amp;quot;的局限。&lt;/p&gt;
&lt;p&gt;但内在限制的本质仍然存在，各家的解法都是在&amp;quot;保证推理质量&amp;quot;和&amp;quot;支持工具调用&amp;quot;之间做权衡。&lt;/p&gt;
&lt;h3 id="76-为什么不支持-fc-就不支持-mcp"&gt;7.6 为什么不支持 FC 就不支持 MCP
&lt;/h3&gt;&lt;p&gt;这个传导关系很直接：MCP 底层完全依赖 Function Calling。如果推理模型不支持 Function Calling，MCP 的&amp;quot;翻译层&amp;quot;（工具定义 → Function Calling 格式转换）就完全失效了，工具信息没办法让模型理解，调用请求也无法被模型生成，整条链路从中间直接断掉。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;推理模型不支持 Function Calling → 不支持 MCP&amp;quot;是一个很自然的传导关系，不是 MCP 本身有什么问题，是底层能力缺失导致的连锁反应。&lt;/p&gt;
&lt;h3 id="本章实践要点-6"&gt;本章实践要点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;冲突的本质是生成范式&lt;/strong&gt;：推理模型的思考链是连续整体，工具调用需要中途暂停，两者天然不兼容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;KV Cache 是暂停的代价&lt;/strong&gt;：保存推理状态要占大量 GPU 显存，在线系统承受不起。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;折中方案的局限&lt;/strong&gt;：让工具调用发生在思考结束后，保证了推理质量但牺牲了&amp;quot;带着工具结果深度推理&amp;quot;的能力。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;interleaved thinking 是缓解不是根治&lt;/strong&gt;：允许在多次工具调用间穿插思考，但根本权衡仍在。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="第八章a2a-协议"&gt;第八章：A2A 协议
&lt;/h2&gt;&lt;h3 id="81-单个-agent-的天花板"&gt;8.1 单个 Agent 的天花板
&lt;/h3&gt;&lt;p&gt;要理解 A2A 是干什么的，得先把&amp;quot;单 Agent 的天花板&amp;quot;搞清楚。一个 Agent 的本质是：&lt;strong&gt;一个 LLM + 一组工具 + 一段上下文窗口&lt;/strong&gt;，这三个维度都有自己的天花板：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;工具数量限制&lt;/strong&gt;：你不可能给一个 Agent 装 100 个工具，模型处理起来效率极低，容易混乱。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上下文窗口限制&lt;/strong&gt;：128K tokens 听起来很多，但复杂任务积累的中间产物（搜索结果、草稿、反思记录）会很快把窗口塞满。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;专业能力限制&lt;/strong&gt;：同一个 Agent 既做代码审查又做市场分析，不如专门配置或微调的 Agent 效果好。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;解决方案很自然：把任务拆开，交给不同的专业 Agent 并行处理，最后汇总。但多 Agent 系统有一个绕不开的基础问题——&lt;strong&gt;Agent 之间怎么互相认识？&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="82-agent-card能力声明与自动发现"&gt;8.2 Agent Card：能力声明与自动发现
&lt;/h3&gt;&lt;p&gt;最笨的方案是写死配置：Agent A 的代码里硬编码&amp;quot;B 可以做竞品分析&amp;rdquo;。这样太脆了，B 的能力一变，A 的代码就得改。&lt;/p&gt;
&lt;p&gt;更好的方案是让 B 主动&amp;quot;发名片&amp;quot;，声明自己能做什么——这就是 A2A 里 &lt;strong&gt;Agent Card&lt;/strong&gt; 的设计思路。每个 A2A Agent 都在一个约定位置发布一张 JSON 格式的名片（推荐路径 &lt;code&gt;/.well-known/agent-card.json&lt;/code&gt;），里面写清楚自己叫什么、能做哪类任务（Skill 列表）、支不支持流式返回、支不支持异步回调。&lt;/p&gt;
&lt;p&gt;任何想和它协作的 Agent，先去拿这张名片，再决定要不要把任务委托给它。这套机制让整个多 Agent 系统变得&lt;strong&gt;可插拔&lt;/strong&gt;：新加一个 Agent，发布它的 Agent Card，调度 Agent 就能自动发现和利用它，完全不需要改调度 Agent 的代码。&lt;/p&gt;
&lt;h3 id="83-task-状态机异步长任务协作"&gt;8.3 Task 状态机：异步长任务协作
&lt;/h3&gt;&lt;p&gt;A2A 里任务协作的基本单位是 &lt;strong&gt;Task&lt;/strong&gt;，有完整的生命周期状态管理：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 创建 开始执行
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌──────────→ submitted ──────────→ working
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ┌─────┴─────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ▼ ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ completed failed
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ (成功) (失败)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 调度Agent可以轮询状态
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 或通过push notification等待回调
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;为什么需要这么完整的状态机？因为 A2A 专门为&lt;strong&gt;长时间任务&lt;/strong&gt;设计。一个&amp;quot;竞品分析&amp;quot;任务可能要跑几分钟——先搜索、再整理、再写报告，不可能让调度 Agent 同步等着。调度 Agent 提交任务后可以去处理其他事情，通过轮询状态或者 push notification（任务完成时接收方主动回调通知）来得知任务完成了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;上下文隔离的核心收益&lt;/strong&gt;：调度 Agent 把&amp;quot;做行业趋势分析&amp;quot;委托给市场 Agent，市场 Agent 自己去搜几十个网页、写草稿、反复迭代，这些中间过程都在它自己的上下文里。任务做完，它只把最终结论（一份几百字的摘要）通过 A2A 返回给调度 Agent。调度 Agent 的上下文里只多了一份摘要，而不是几十个网页的原文——调研过程的上下文压力被隔离在了市场 Agent 内部。&lt;/p&gt;
&lt;h3 id="84-agent-的微服务化"&gt;8.4 Agent 的微服务化
&lt;/h3&gt;&lt;p&gt;如果你有后端开发经验，A2A 其实不陌生：它就是 &lt;strong&gt;Agent 世界里的微服务架构&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;微服务概念&lt;/th&gt;
&lt;th&gt;A2A 对应&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;服务独立部署&lt;/td&gt;
&lt;td&gt;Agent 独立部署为 HTTP 服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API 文档&lt;/td&gt;
&lt;td&gt;Agent Card&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;异步消息队列&lt;/td&gt;
&lt;td&gt;Task 状态机&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;服务注册中心&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.well-known/agent-card.json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP 互相调用&lt;/td&gt;
&lt;td&gt;Agent 间 A2A 通信&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;每个 A2A Agent 对外就是一个 HTTP 服务，任何支持 A2A 的系统都可以发现它、向它发任务、接收结果，不绑定特定的 AI 框架，也不依赖特定的编程语言。这个设计理念和 MCP 是一脉相承的：&lt;strong&gt;MCP 让工具成为独立标准化服务，A2A 让 Agent 成为独立标准化服务&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="85-a2a-与-mcp一纵一横各管一层"&gt;8.5 A2A 与 MCP：一纵一横，各管一层
&lt;/h3&gt;&lt;p&gt;理清两者关系最简单的方式是看方向：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 调度 Agent (Agent A) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ┌──A2A──→ 市场分析Agent (B) │ ← 横向:A2A
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├──A2A──→ 技术研究Agent (C) │ (Agent间协作)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├──A2A──→ 报告撰写Agent (D) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ ┌──MCP──→ 数据库工具 │ ← 纵向:MCP
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ ├──MCP──→ 文件系统工具 │ (Agent连工具)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ └──MCP──→ 代码执行器 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──┴───────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MCP 是 Agent 向下连工具&lt;/strong&gt;（纵向）：数据库、浏览器、代码执行器。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A2A 是 Agent 向外连其他 Agent&lt;/strong&gt;（横向）：任务委派、结果接收。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;打个比方，MCP 就像公司里每个员工的&amp;quot;工具箱&amp;quot;，决定了这个人能用什么工具干活。A2A 就像公司里的&amp;quot;协作流程&amp;quot;，决定了不同岗位的人怎么分工、怎么交接任务。工具箱和协作流程是两回事，缺了哪个都不行。在复杂的多 Agent 系统里，这两者通常同时在用。&lt;/p&gt;
&lt;h3 id="本章实践要点-7"&gt;本章实践要点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A2A 不是 MCP 的竞品&lt;/strong&gt;：MCP 向下连工具，A2A 向外连 Agent，方向完全不同。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent Card 是自动发现的基础&lt;/strong&gt;：新 Agent 发布名片即可被发现，调度 Agent 无需改代码。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Task 状态机专为长任务设计&lt;/strong&gt;：支持异步、轮询、push notification，调度 Agent 保持轻量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本质是微服务架构&lt;/strong&gt;：Agent 对外就是 HTTP 服务，可独立部署、跨框架、跨语言。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="第九章通信协议对比"&gt;第九章：通信协议对比
&lt;/h2&gt;&lt;h3 id="91-从-http-的本质说起"&gt;9.1 从 HTTP 的本质说起
&lt;/h3&gt;&lt;p&gt;要理解各种通信协议的区别，得先回到一个根本问题：它们到底在解决什么问题？答案是普通 HTTP 做不到的事情。&lt;/p&gt;
&lt;p&gt;标准 HTTP 是&amp;quot;一问一答&amp;quot;模型：客户端发请求，服务端返回响应，连接关闭。服务端在任何时候都不能主动&amp;quot;推&amp;quot;数据给客户端。但 AI 对话场景不行——模型生成一个完整回答需要几秒甚至十几秒，如果等全部生成完再一次性返回，用户只能干瞪着空白屏幕等待。我们需要的效果是：模型生成一个词就推一个词，用户实时看到文字逐渐出现。&lt;/p&gt;
&lt;h3 id="92-sse用普通-http-撑开一条单向水管"&gt;9.2 SSE：用普通 HTTP 撑开一条单向水管
&lt;/h3&gt;&lt;p&gt;SSE（Server-Sent Events）本质上是对 HTTP 的一种&amp;quot;巧用&amp;quot;，不是新协议，而是 HTTP/1.1 里本来就有的特性。客户端发一个普通 GET 请求，但在请求头声明 &lt;code&gt;Accept: text/event-stream&lt;/code&gt;，服务端收到后不关闭连接，保持持续打开，不停往里写数据。这条连接在技术上仍然是一个 HTTP 响应，只不过响应体是&amp;quot;无限长&amp;quot;的。&lt;/p&gt;
&lt;p&gt;可以把它理解为&amp;quot;一根从服务端流向客户端的单向水管&amp;quot;，水只能从服务端流向客户端。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;为什么 SSE 成为 LLM 流式输出的行业标准？&lt;/strong&gt; 有一个关键但容易被忽视的原因：文字传输天然适合 TCP 的可靠有序传输。模型输出是连续文本，如果中间某个 token 丢了，整段话的意思可能完全变了。所以你希望每个 token 都准确到达、不乱序——这恰恰是 TCP 的强项，你愿意等网络重传，因为等来的是正确的内容。这和语音场景完全相反，那里 TCP 的重传会造成不可接受的延迟。&lt;/p&gt;
&lt;h3 id="93-websocket从-http-升级成全双工信道"&gt;9.3 WebSocket：从 HTTP 升级成全双工信道
&lt;/h3&gt;&lt;p&gt;WebSocket 是一个独立协议，建立在 TCP 之上，但不是 HTTP 的特性。建立过程有一个特殊的&amp;quot;握手仪式&amp;quot;：客户端先发一个看起来像普通 HTTP 请求的东西，但请求头带了&amp;quot;我想升级成 WebSocket&amp;quot;。服务端如果同意，回一个 &lt;code&gt;101 Switching Protocols&lt;/code&gt; 响应，从这一刻起这条 TCP 连接就&amp;quot;变性&amp;quot;了，变成双方都可以随时说话的全双工信道。&lt;/p&gt;
&lt;p&gt;和 SSE 最本质的区别是通信方向：SSE 只有服务端能主动推，客户端想发消息必须另起一个 HTTP 请求；WebSocket 是真正的双向，客户端和服务端都可以随时主动发消息。&lt;/p&gt;
&lt;h3 id="94-webrtc为实时语音选择-udp"&gt;9.4 WebRTC：为实时语音选择 UDP
&lt;/h3&gt;&lt;p&gt;语音场景和文字场景对网络的要求完全相反。人类大脑对语音时序极其敏感，超过 200ms 延迟就会明显感觉到&amp;quot;卡顿&amp;quot;。丢掉一个 20ms 的音频片段不是大事，人耳感知不到一小段静音；但为了等这 20ms 的片段重传，把后续所有音频都堵住，延迟积累到几百毫秒，体验就彻底崩了。&lt;strong&gt;语音容忍丢包，绝不容忍延迟&lt;/strong&gt;，TCP 的设计哲学正好和这个需求相反。&lt;/p&gt;
&lt;p&gt;WebRTC 把底层从 TCP 换成 UDP，丢包了不等重传，直接用&amp;quot;丢包隐藏（Packet Loss Concealment）&amp;ldquo;技术自动填补——用前后帧插值生成一段听起来合理的音频来替代，整体播放不中断，只是极短暂的音质轻微下降。延迟能控制在 50-150 毫秒。&lt;/p&gt;
&lt;p&gt;WebRTC 还内置了回声消除（AEC）、噪声抑制（NS）、自动增益控制（AGC）、自适应码率（ABR）这些语音处理能力，这些用 WebSocket 全得自己造轮子。&lt;/p&gt;
&lt;h3 id="95-四种传输方式对比"&gt;9.5 四种传输方式对比
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;SSE&lt;/th&gt;
&lt;th&gt;WebSocket&lt;/th&gt;
&lt;th&gt;WebRTC&lt;/th&gt;
&lt;th&gt;stdio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;底层协议&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTTP/1.1（特性）&lt;/td&gt;
&lt;td&gt;TCP（独立协议）&lt;/td&gt;
&lt;td&gt;UDP（协议族）&lt;/td&gt;
&lt;td&gt;OS 管道&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;通信方向&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;服务端单向推&lt;/td&gt;
&lt;td&gt;全双工&lt;/td&gt;
&lt;td&gt;全双工（P2P）&lt;/td&gt;
&lt;td&gt;双向（管道）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;延迟&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;低（TCP）&lt;/td&gt;
&lt;td&gt;50-500ms（受TCP重传影响）&lt;/td&gt;
&lt;td&gt;50-150ms（UDP不重传）&lt;/td&gt;
&lt;td&gt;极低（内存）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;连接数限制&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTTP/1.1同域6条&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;二进制支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;否（需Base64膨胀33%）&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;是（原生音视频）&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;横向扩展&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;简单（无状态HTTP）&lt;/td&gt;
&lt;td&gt;麻烦（有状态需Redis）&lt;/td&gt;
&lt;td&gt;复杂（需信令服务器）&lt;/td&gt;
&lt;td&gt;不适用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;代理穿透&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;好（普通HTTP）&lt;/td&gt;
&lt;td&gt;差（Upgrade易被拦）&lt;/td&gt;
&lt;td&gt;差（需ICE/STUN/TURN）&lt;/td&gt;
&lt;td&gt;不适用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;适合场景&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LLM文字流式输出&lt;/td&gt;
&lt;td&gt;双向实时交互&lt;/td&gt;
&lt;td&gt;实时音视频&lt;/td&gt;
&lt;td&gt;MCP本地工具&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="96-选型决策"&gt;9.6 选型决策
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;推荐方案&lt;/th&gt;
&lt;th&gt;原因&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LLM 流式文字输出（ChatGPT 风格）&lt;/td&gt;
&lt;td&gt;SSE&lt;/td&gt;
&lt;td&gt;单向推送够用，轻量，HTTP 原生支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;多轮对话（用户发消息 + 模型回复）&lt;/td&gt;
&lt;td&gt;SSE + POST&lt;/td&gt;
&lt;td&gt;用户发消息走 POST，模型回复走 SSE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;需要用户中途打断模型输出&lt;/td&gt;
&lt;td&gt;WebSocket&lt;/td&gt;
&lt;td&gt;需要客户端在流式输出中途主动发消息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;多人协同（实时同步）&lt;/td&gt;
&lt;td&gt;WebSocket&lt;/td&gt;
&lt;td&gt;频繁双向消息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;实时语音对话&lt;/td&gt;
&lt;td&gt;WebRTC&lt;/td&gt;
&lt;td&gt;音频流需要 UDP + 低延迟&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP 本地 Server&lt;/td&gt;
&lt;td&gt;stdio&lt;/td&gt;
&lt;td&gt;不走网络、延迟极低、生命周期自动管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP 远程 Server&lt;/td&gt;
&lt;td&gt;Streamable HTTP&lt;/td&gt;
&lt;td&gt;多 Client 共享、跨机器访问&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;大原则是：&lt;strong&gt;单向推用 SSE，真正需要双向才上 WebSocket，实时语音必须 WebRTC，本地进程间用 stdio&lt;/strong&gt;。绝大多数 LLM 文字对话产品用 SSE 就够了，这也是 OpenAI、Anthropic 的 API 都选 SSE 而不是 WebSocket的原因。&lt;/p&gt;
&lt;h3 id="本章实践要点-8"&gt;本章实践要点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SSE 不是 WebSocket 的子集&lt;/strong&gt;：SSE 是 HTTP 原生特性，WebSocket 是独立协议，底层机制完全不同。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSE 的三个坑&lt;/strong&gt;：HTTP/1.1 同域连接数上限（6条）、只支持文本（二进制需 Base64 膨胀 33%）、单向性导致双通道架构。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebSocket 的三个坑&lt;/strong&gt;：有状态导致横向扩展麻烦、容易被企业代理/防火墙拦截 Upgrade 握手、没有内置请求-响应配对机制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebRTC 建连仍需 WebSocket&lt;/strong&gt;：WebSocket 负责信令交换（SDP），真正的音频流走 UDP，两者是配合不是替代。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;stdio 是 MCP 本地首选&lt;/strong&gt;：不经过网卡、不需要端口、生命周期自动管理。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="第十章llm-网关"&gt;第十章：LLM 网关
&lt;/h2&gt;&lt;h3 id="101-网关是什么放在哪"&gt;10.1 网关是什么，放在哪
&lt;/h3&gt;&lt;p&gt;没有网关时，你的应用直接对接各个模型 API：应用 → OpenAI API、应用 → Anthropic API、应用 → 其他 API。有了网关之后，调用链变成：&lt;strong&gt;应用 → 网关 → OpenAI/Anthropic/其他 API&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;网关就是一个&amp;quot;中间人&amp;rdquo;，坐在你的应用和各个模型 API 之间。你的应用只认识网关，不需要直接对接多个 API。这个&amp;quot;中间人&amp;quot;的定位是理解网关所有功能的基础——它集中拦截和处理了所有出入流量，所以能在这个位置统一做很多事情。&lt;/p&gt;
&lt;h3 id="102-没有网关时的痛点"&gt;10.2 没有网关时的痛点
&lt;/h3&gt;&lt;p&gt;一个稍微大一点的 AI 产品，同时用多个模型是常态：主流程用 GPT-4o，成本敏感的任务用 GPT-4o-mini，代码任务用 Claude Sonnet，向量化用 text-embedding-3-small。每家厂商的 SDK 不一样、鉴权方式不一样、参数格式也有细微差异。如果不做网关，这些差异会渗透到每个业务服务里，带来一连串麻烦：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;安全问题&lt;/strong&gt;：API Key 散落在各个服务的配置文件里，任何一处泄露都是安全事故。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重复劳动&lt;/strong&gt;：每个服务都要自己写重试和限流逻辑，版本还不一样。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;成本黑箱&lt;/strong&gt;：各服务各记各的，月底无法统计哪个业务线花了多少钱。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活性差&lt;/strong&gt;：想换模型、想限制调用量都得改代码。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些问题都源自同一个根本原因：&lt;strong&gt;没有一个集中的地方来统一管理这些&amp;quot;横切关注点&amp;quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="103-六大核心功能"&gt;10.3 六大核心功能
&lt;/h3&gt;&lt;h4 id="功能一多模型统一接口"&gt;功能一：多模型统一接口
&lt;/h4&gt;&lt;p&gt;大多数 LLM 网关对外暴露一个 OpenAI 兼容的接口。业务代码只需要改两个地方：把 &lt;code&gt;base_url&lt;/code&gt; 指向网关地址，把 &lt;code&gt;api_key&lt;/code&gt; 换成网关分配的虚拟 Key，其他代码一行不动。换模型只改网关路由配置，&amp;ldquo;换模型&amp;quot;这件事对业务层彻底隐形。&lt;/p&gt;
&lt;h4 id="功能二api-key-集中管理"&gt;功能二：API Key 集中管理
&lt;/h4&gt;&lt;p&gt;API Key 只存在网关这一个地方，业务服务拿到的是网关分配的虚拟 Key，根本接触不到真实密钥。降低泄漏风险。&lt;/p&gt;
&lt;h4 id="功能三负载均衡和故障转移"&gt;功能三：负载均衡和故障转移
&lt;/h4&gt;&lt;p&gt;给同一个&amp;quot;模型名&amp;quot;配置多条路由规则，主路由指向 OpenAI，备用路由指向 Azure OpenAI 或 Anthropic。主路由连续失败达到阈值时，网关自动切换到备用路由，业务层完全无感知。&lt;/p&gt;
&lt;h4 id="功能四限流和配额"&gt;功能四：限流和配额
&lt;/h4&gt;&lt;p&gt;给每个团队的虚拟 Key 设置独立的 token 日预算。一旦超出配额，该 Key 的请求直接返回 429，其他团队不受影响。&lt;/p&gt;
&lt;h4 id="功能五成本追踪和可观测性"&gt;功能五：成本追踪和可观测性
&lt;/h4&gt;&lt;p&gt;网关集中记录每次调用的 token 用量、响应时间、错误率，可以回答&amp;quot;哪个接口最烧钱&amp;quot;&amp;ldquo;各团队用了多少&amp;quot;这类问题。通常可以直接对接 Langfuse、Prometheus 等监控系统。&lt;/p&gt;
&lt;h4 id="功能六语义缓存llm-网关的亮点"&gt;功能六：语义缓存（LLM 网关的亮点）
&lt;/h4&gt;&lt;p&gt;这是 LLM 网关区别于普通 API 网关的关键能力。普通 HTTP 缓存是精确匹配，请求内容一字不差才能命中。但 LLM 的问题往往有大量语义相近的变体：&amp;ldquo;北京今天热吗&amp;quot;&amp;ldquo;北京现在天气怎样&amp;quot;&amp;ldquo;今天北京气温多少&amp;rdquo;——三个问题本质上是同一个需求，精确匹配全部 miss。&lt;/p&gt;
&lt;p&gt;语义缓存的核心原理是：把用户问题转换成一个向量（embedding），然后在向量数据库里做相似度搜索，如果找到一个指纹很接近的历史问题（相似度超过设定阈值），就直接返回那次的答案，&lt;strong&gt;完全跳过 LLM 调用&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 语义缓存的简化流程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;semantic_cache_lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_question&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 1. 把问题向量化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;question_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 2. 在向量数据库里做相似度搜索&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;similar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vector_db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;question_vector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.90&lt;/span&gt; &lt;span class="c1"&gt;# 相似度阈值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;similar&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;similar&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.90&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 3. 命中缓存，直接返回历史答案&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;similar&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;answer&lt;/span&gt; &lt;span class="c1"&gt;# 跳过 LLM 调用!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 4. 未命中，调 LLM 并缓存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vector_db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question_vector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;语义缓存要用好，有两个工程细节需要注意：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;相似度阈值怎么设&lt;/strong&gt;：太高（0.99）只有一模一样的问题才命中，缓存形同虚设；太低（0.7）可能出现&amp;quot;北京今天热吗&amp;quot;命中了&amp;quot;上海今天热吗&amp;quot;的答案。通常在 0.85-0.95 之间调试。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缓存有效期&lt;/strong&gt;：天气、股价这类实时信息缓存几分钟就够；产品 FAQ、技术文档这类稳定知识缓存几天甚至更长。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="104-prompt-安全过滤"&gt;10.4 Prompt 安全过滤
&lt;/h3&gt;&lt;p&gt;在网关层可以统一做输入输出的安全校验，包括检测 prompt 注入攻击、过滤个人隐私信息（身份证号、手机号不应该被发送到外部 API）、内容安全审核。集中在网关做的好处是不需要每个业务服务各自实现，安全策略统一更新，任何一个接入点都自动获得保护。&lt;/p&gt;
&lt;h3 id="105-常见网关框架对比"&gt;10.5 常见网关框架对比
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;框架&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LiteLLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;开源，Python&lt;/td&gt;
&lt;td&gt;支持 100+ 模型，OpenAI 兼容接口，社区最活跃（注意关注安全公告）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bifrost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;开源，Rust&lt;/td&gt;
&lt;td&gt;高性能低延迟，2026 年新兴，适合对性能要求高的场景&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PortKey&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;商业+开源&lt;/td&gt;
&lt;td&gt;功能完整，有托管版，适合不想自运维的团队&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Kong AI Gateway&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;商业（Kong 扩展）&lt;/td&gt;
&lt;td&gt;基于成熟的 Kong 网关扩展 AI 能力，适合已有 Kong 的团队&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;One API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;开源，Go&lt;/td&gt;
&lt;td&gt;国内社区活跃，支持国产模型，部署简单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nginx/Envoy 自研&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;自研&lt;/td&gt;
&lt;td&gt;灵活但工作量大，适合有特殊需求的大厂&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="本章实践要点-9"&gt;本章实践要点
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不是普通 API 网关&lt;/strong&gt;：LLM 网关除了统一接口和负载均衡，更核心的价值是 token 配额、语义缓存、prompt 安全这些 LLM 特有能力。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;语义缓存阈值要调&lt;/strong&gt;：0.85-0.95 是常见范围，具体看场景和用户提问多样性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;虚拟 Key 隔离风险&lt;/strong&gt;：业务服务接触不到真实密钥，降低泄漏风险。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;故障转移保障可用性&lt;/strong&gt;：多路由配置 + 自动切换，业务层无感知。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全事件要关注&lt;/strong&gt;：LiteLLM 在 2026 年 3 月发生过供应链安全事件，生产环境建议版本锁定和校验。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="核心知识点回顾"&gt;核心知识点回顾
&lt;/h2&gt;&lt;h3 id="关键认知"&gt;关键认知
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;模型只决策不执行&lt;/strong&gt;——这是整个工具调用体系的基石。模型输出结构化 JSON，代码负责执行。LLM 擅长理解意图和推理，但不应该有直接操作系统资源的权限。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SFT 教会怎么调，RLHF 教会什么时候调&lt;/strong&gt;——两个阶段缺一不可。只有 SFT 模型会过激调用，只有 RLHF 模型连格式都输不出来。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MCP 底层靠 Function Calling 驱动&lt;/strong&gt;——模型感知不到 MCP 的存在。MCP 是工具箱层，FC 是调用语言层，不是竞争关系。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;三层架构缺一不可&lt;/strong&gt;——Function Calling 是&amp;quot;手&amp;rdquo;（调用语言），MCP 是&amp;quot;厨房&amp;rdquo;（工具箱），Skill 是&amp;quot;菜谱&amp;rdquo;（操作手册）。Skill 定义流程 → MCP 提供工具 → Function Calling 触发调用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;推理模型与工具调用的冲突是范式性的&lt;/strong&gt;——思考链是连续整体，工具调用需要中途暂停。折中方案让工具调用发生在思考结束后，interleaved thinking 部分缓解了局限。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A2A 和 MCP 一纵一横&lt;/strong&gt;——MCP 向下连工具（纵向），A2A 向外连 Agent（横向）。复杂多 Agent 系统两者都要用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;通信协议选型看场景&lt;/strong&gt;——文字用 SSE，双向实时用 WebSocket，语音用 WebRTC，本地进程间用 stdio。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LLM 网关的核心差异化是语义缓存&lt;/strong&gt;——这是普通 API 网关做不到的，用向量相似度匹配语义相近问题，跳过 LLM 调用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="技术栈全景速查"&gt;技术栈全景速查
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;╔══════════════════════════════════════════════════════════════╗&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;用户&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;业务应用&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;╠══════════════════════════════════════════════════════════════╣&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;┌─&lt;/span&gt; &lt;span class="n"&gt;A2A&lt;/span&gt; &lt;span class="err"&gt;──────────────────────────────────────────────────┐&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;Agent间协作&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt; &lt;span class="n"&gt;Card&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;Task状态机&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;微服务化&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;└────────────────────────────────────────────────────────┘&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;┌─&lt;/span&gt; &lt;span class="n"&gt;Skill&lt;/span&gt; &lt;span class="err"&gt;────────────────────────────────────────────────┐&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;任务流程知识化&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SKILL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;scripts&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;渐进式加载&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;└────────────────────────────────────────────────────────┘&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;┌─&lt;/span&gt; &lt;span class="n"&gt;MCP&lt;/span&gt; &lt;span class="err"&gt;──────────────────────────────────────────────────┐&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;工具标准化&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;Tools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Resources&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Prompts&lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;传输&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;stdio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;本地&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;Streamable&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;远程&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;消息&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;RPC&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;└────────────────────────────────────────────────────────┘&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;┌─&lt;/span&gt; &lt;span class="n"&gt;Function&lt;/span&gt; &lt;span class="n"&gt;Calling&lt;/span&gt; &lt;span class="err"&gt;─────────────────────────────────────┐&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;调用语言&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;schema定义&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tool_calls&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;两轮对话&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;训练&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SFT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;怎么调&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;RLHF&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;PPO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;该不该调&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;└────────────────────────────────────────────────────────┘&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;┌─&lt;/span&gt; &lt;span class="n"&gt;LLM&lt;/span&gt; &lt;span class="err"&gt;网关&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;横切中间件&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;────────────────────────────────┐&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;统一接口&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;Key管理&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;负载均衡&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;配额&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;成本追踪&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;语义缓存&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;Prompt安全&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;└────────────────────────────────────────────────────────┘&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;┌─&lt;/span&gt; &lt;span class="err"&gt;通信协议&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;横切基础设施&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;───────────────────────────────┐&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="n"&gt;SSE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;文字流&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;双向&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;WebRTC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;语音&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;stdio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;本地&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;└────────────────────────────────────────────────────────┘&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;╠══════════════════════════════════════════════════════════════╣&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;║&lt;/span&gt; &lt;span class="err"&gt;各家模型&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OpenAI&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Anthropic&lt;/span&gt;&lt;span class="o"&gt;/...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;║&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;╚══════════════════════════════════════════════════════════════╝&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="主题关联"&gt;主题关联
&lt;/h3&gt;&lt;p&gt;本文涉及的各主题之间有着紧密的逻辑递进关系：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Function Calling&lt;/strong&gt; 是整条技术栈的地基，没有它上层一切都无从谈起。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;训练（SFT+RLHF）&lt;/strong&gt; 解释了 Function Calling 能力从何而来，理解了训练才能理解为什么推理模型会冲突。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MCP&lt;/strong&gt; 在 Function Calling 之上解决工具管理问题，但本质还是靠 FC 驱动。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skill&lt;/strong&gt; 在 MCP 之上解决流程知识问题，三层共同构成完整的 Agent 能力栈。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;推理模型冲突&lt;/strong&gt; 是 Function Calling 的一个&amp;quot;边界案例&amp;rdquo;，揭示了工具调用并非万能，有范式上的约束。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A2A&lt;/strong&gt; 把视角从单 Agent 扩展到多 Agent，和 MCP 形成&amp;quot;纵向+横向&amp;quot;的互补。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通信协议&lt;/strong&gt; 是支撑以上所有机制的底层基础设施，选对协议直接影响系统性能。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM 网关&lt;/strong&gt; 是横切所有上层应用的中间件，解决工程化和治理问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="进一步阅读"&gt;进一步阅读
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Function Calling 官方文档&lt;/strong&gt;：OpenAI Function Calling Guide、Anthropic Tool Use 文档&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MCP 规范&lt;/strong&gt;：Anthropic Model Context Protocol 官方规范（2025-03-26 版本）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent Skills&lt;/strong&gt;：Anthropic Agent Skills 开放标准规范（2025 年 12 月发布）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A2A 协议&lt;/strong&gt;：Google Agent-to-Agent Protocol 规范&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通信协议深入&lt;/strong&gt;：MDN SSE/WebSocket 文档、WebRTC 官方文档&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM 网关&lt;/strong&gt;：LiteLLM 文档、GPTCache（语义缓存实现）文档&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;系列导航&lt;/strong&gt;：本文是「AI 知识体系深度解析」系列第三篇。前序篇章覆盖 LLM 基础架构与训练原理，后续篇章将深入 Agent 系统设计与多模态应用，敬请关注。&lt;/p&gt;&lt;/blockquote&gt;</description></item><item><title>RAG检索增强生成——从原理到工程落地</title><link>https://blog.irudder.me/ai/ai-systematization/02-RAG-Retrieval-Augmented-Generation.html</link><pubDate>Sat, 25 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/ai-systematization/02-RAG-Retrieval-Augmented-Generation.html</guid><description>&lt;h1 id="rag检索增强生成从原理到工程落地"&gt;RAG检索增强生成——从原理到工程落地
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;本文是「AI 大模型工程知识体系」系列的第 02 篇。RAG（Retrieval-Augmented Generation，检索增强生成）是企业 AI 落地最核心的技术范式之一——它让大模型在回答问题时&amp;quot;有据可依&amp;quot;，而非凭记忆发挥。本文将从 RAG 的本质出发，逐层拆解文档切割、Embedding、向量数据库、在线检索、检索优化、高级范式与生产落地的完整知识体系，力求让读者既能理解原理，又能动手工程实践。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="核心问题列表"&gt;核心问题列表
&lt;/h2&gt;&lt;p&gt;在进入正文之前，先抛出本文要回答的核心问题，带着问题阅读效果更好：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;RAG 到底是什么？&lt;/strong&gt; 它解决了 LLM 的哪些根本问题？和微调的本质区别在哪？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文档为什么要切割？&lt;/strong&gt; 有哪些切割策略？chunk_size 怎么定？语义被切断怎么规避？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Embedding 的原理是什么？&lt;/strong&gt; 从 one-hot 到稠密向量经历了怎样的演进？如何选型和评估？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;向量数据库和普通数据库有什么不同？&lt;/strong&gt; HNSW 和 IVF 索引算法各自适合什么场景？生产环境怎么选型？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在线检索的完整流程是什么？&lt;/strong&gt; 粗排和精排有何区别？多路召回怎么做？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;检索效果不好从哪里优化？&lt;/strong&gt; Query 层、检索层、结果层、生成层各自解决什么问题？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Self-RAG、CRAG、GraphRAG、LightRAG 这些高级范式各自解决什么痛点？&lt;/strong&gt; 该怎么选？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAG 上生产有哪些难点？&lt;/strong&gt; 幻觉怎么规避？效果怎么量化？知识库怎么动态更新？&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="引言为什么大模型需要开卷考试"&gt;引言：为什么大模型需要&amp;quot;开卷考试&amp;quot;
&lt;/h2&gt;&lt;p&gt;一个 LLM（大语言模型）训练完成之后，它的知识就&amp;quot;冻结&amp;quot;了。训练数据截止日期之后发生的事情它一无所知，你们公司内部的私有文档它更不知道。就好比一个人高考之后再也不看新闻，你问他今天的股价，他怎么可能答得上来？&lt;/p&gt;
&lt;p&gt;那能不能靠微调来更新知识？理论上可以，但微调成本高、耗时长，最关键的是知识一旦写进模型参数，以后想更新就得重新训练一遍——这就好比你为了让一个人记住一条新闻，让他重新上了一遍大学，太不划算了。&lt;/p&gt;
&lt;p&gt;RAG 走了一条完全不同的路：&lt;strong&gt;不把知识塞进模型参数里，而是在用户提问的时候，实时去外部知识库检索相关内容，把检索结果和用户的问题一起交给 LLM，让它基于这些上下文来回答。&lt;/strong&gt; 本质上就是给 LLM 开了一个&amp;quot;开卷考试&amp;quot;的口子，不用再靠死记硬背。&lt;/p&gt;
&lt;p&gt;这个设计思路让知识管理和模型能力彻底解耦：更新知识不需要碰模型，扩充领域知识只需要扩充知识库，这也是 RAG 成为企业 AI 落地首选方案的根本原因。&lt;/p&gt;
&lt;p&gt;接下来，我们从 RAG 的本质开始，逐层深入。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第一章rag-的本质与价值"&gt;第一章：RAG 的本质与价值
&lt;/h2&gt;&lt;h3 id="11-rag-解决的三大问题"&gt;1.1 RAG 解决的三大问题
&lt;/h3&gt;&lt;p&gt;要理解 RAG 的价值，得先搞清楚 LLM 到底差在哪。LLM 的&amp;quot;知识&amp;quot;是训练时通过海量文本学到的，最终以权重参数的形式固化在模型里——就像把知识烧进了 ROM，训练完成之后就刻在那里了，不会自动更新。这个特性导致了三个环环相扣的问题：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题一：知识时效性（知识过期）。&lt;/strong&gt; LLM 训练数据有截止日期，之后发生的事它不知道，但它不会说&amp;quot;我不知道&amp;quot;，而是会&amp;quot;推测&amp;quot;出一个听起来合理的答案。金融场景里用 LLM 辅助分析，如果模型不知道某公司最近一季度的财报数据，给出的分析就是基于过期信息的，参考价值大打折扣。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题二：私有知识覆盖（知识空白）。&lt;/strong&gt; 公开互联网上的知识 LLM 或多或少见过，但每家公司的内部文档——产品手册、客服知识库、合同模板、行业规范——这些东西根本不会出现在公开训练数据里。你让 LLM 扮演客服机器人回答&amp;quot;我们产品的退款政策是什么&amp;quot;，它不可能知道，因为它压根没见过这条信息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题三：幻觉问题（知识缺失的副产品）。&lt;/strong&gt; 前两个问题都指向同一个现象——幻觉。LLM 的核心机制是&amp;quot;预测下一个词&amp;quot;，它没有内置&amp;quot;我不确定就停下来&amp;quot;的开关。当参数里的知识不够用时，它只能硬着头皮往下生成，把相关的、不相关的知识拼凑出一个&amp;quot;听起来合理&amp;quot;的答案。&lt;/p&gt;
&lt;p&gt;很多人有个误区，以为幻觉是 LLM 的一个独立 bug，需要单独治理。其实不是，&lt;strong&gt;幻觉是知识缺失的副产品&lt;/strong&gt;，是模型在没有可靠依据时的&amp;quot;应急策略&amp;quot;。根源都是同一件事：模型参数里没有对应的知识。&lt;/p&gt;
&lt;p&gt;RAG 的解法一招对三症：把知识存到外部知识库，用的时候实时检索注入，彻底绕开参数里的知识限制。知识过期——新内容随时入库，不需要重新训练；知识缺失——公司文档入库后 LLM 就能&amp;quot;看到&amp;quot;这些内容；幻觉——LLM 有了真实参考依据，生成答案时是在&amp;quot;复述&amp;quot;检索到的内容，而非凭记忆发挥。&lt;/p&gt;
&lt;h3 id="12-rag-的完整工作流程"&gt;1.2 RAG 的完整工作流程
&lt;/h3&gt;&lt;p&gt;一个完整的 RAG 系统分&lt;strong&gt;离线（索引）&lt;/strong&gt; 和&lt;strong&gt;在线（查询）&lt;/strong&gt; 两个阶段，分工明确：离线负责建库，在线负责检索和生成。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ RAG 完整架构 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────┬───────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 离线阶段（建库） │ 在线阶段（检索+生成） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 只做一次，反复使用 │ 每次用户提问实时执行 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────┼───────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 文档加载(PDF/Word/MD) │ 用户提问 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 文档切割(Chunking) │ Query预处理(改写/HyDE/扩展) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 500~1000 token/块 │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │ Query向量化(同款Embedding) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 向量化(Embedding) │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 文本→1024维向量 │ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ 向量检索(粗排)+多路召回(BM25) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │ Top-20候选 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 入库(向量数据库) │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 向量+原文+metadata │ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Rerank精排(Cross-Encoder) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Top-3~5高质量片段 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Prompt拼装(资料+问题+约束) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ LLM生成答案 + 引用溯源 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────┴───────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;离线阶段四步走：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;文档加载&lt;/strong&gt;：把 PDF、Word、Markdown、网页等各格式数据读取进来。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文档切割（Chunking）&lt;/strong&gt;：把文档切成小片段（chunk），因为 Embedding 模型有输入长度限制，且整篇文档压缩成一个向量会丢失细节。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;向量化（Embedding）&lt;/strong&gt;：把每个 chunk 转成高维数字向量，语义相近的文本在向量空间里距离近。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;入库&lt;/strong&gt;：把向量 + 原始文本 + metadata 存进向量数据库。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;在线阶段六步走：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Query 预处理&lt;/strong&gt;：把口语化、带指代的问题改写成更适合检索的形式。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Query 向量化&lt;/strong&gt;：用和建库时完全相同的 Embedding 模型把问题转成向量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;向量检索（粗排）+ 多路召回&lt;/strong&gt;：在向量库里做 ANN 搜索找 Top-K，通常同时走 BM25 关键词检索。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rerank 精排&lt;/strong&gt;：用 Cross-Encoder 深度理解 query 和每个候选的相关性，重排序留下 Top-3~5。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prompt 拼装&lt;/strong&gt;：把精排后的 chunk 和用户问题组装成 Prompt，明确约束 LLM 只根据资料回答。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM 生成 + 溯源&lt;/strong&gt;：LLM 基于参考资料生成答案，标注每句话来自哪个片段。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="13-rag-vs-微调不是二选一而是互补"&gt;1.3 RAG vs 微调：不是二选一，而是互补
&lt;/h3&gt;&lt;p&gt;RAG 和微调（Fine-tuning）解决的不是同一层面的问题。理解 LLM 知识的本质——&amp;ldquo;知识固化在参数里&amp;rdquo;——就能理解为什么需要这两种方案：它们本质上都是在解决同一个问题（怎么把模型训练时没学到的知识补上），但思路完全不同。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;微调（Fine-tuning）&lt;/th&gt;
&lt;th&gt;RAG&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;本质&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;把知识烧进模型参数&lt;/td&gt;
&lt;td&gt;不改参数，推理时实时检索注入&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;知识更新&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;需要重新训练，成本高&lt;/td&gt;
&lt;td&gt;更新知识库即可，实时生效&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;推理延迟&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;低，无额外检索步骤&lt;/td&gt;
&lt;td&gt;较高，多一次检索耗时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;实现成本&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;高，需 GPU 和标注数据&lt;/td&gt;
&lt;td&gt;低，向量库 + Embedding 即可&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;答案可溯源&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;不支持，来自模型参数&lt;/td&gt;
&lt;td&gt;支持，可追溯到具体 chunk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;适合场景&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;定制输出风格、深度专业能力&lt;/td&gt;
&lt;td&gt;私有知识问答、动态更新数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;知识上限&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;受限于训练数据质量和规模&lt;/td&gt;
&lt;td&gt;受限于检索质量和 context 长度&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一个关键的直觉认知：&lt;strong&gt;生成层（LLM）只是在复述和整理检索到的内容，它的上限被检索层死死卡住。&lt;/strong&gt; 你只能回答你检索到的知识，没检索到的东西 LLM 是变不出来的。所以 RAG 系统调优的主战场永远是检索这一层，不是换更强的 LLM。&lt;/p&gt;
&lt;p&gt;实际工程中最常见的做法是&lt;strong&gt;组合使用&lt;/strong&gt;：先微调让模型学会输出格式、语气风格、行业术语；再用 RAG 提供具体知识内容。微调解决&amp;quot;怎么说&amp;quot;，RAG 解决&amp;quot;说什么&amp;quot;，各司其职。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;本章实践要点&lt;/strong&gt;：做 RAG 选型决策时，先问自己&amp;quot;知识是否需要频繁更新&amp;quot;和&amp;quot;答案是否需要可溯源&amp;quot;。如果两个都是 Yes，RAG 是首选；如果只是要定制输出风格，微调更合适。生产环境推荐&amp;quot;微调打基础 + RAG 补知识&amp;quot;的组合拳。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第二章文档切割策略"&gt;第二章：文档切割策略
&lt;/h2&gt;&lt;h3 id="21-为什么文档不能直接存"&gt;2.1 为什么文档不能直接存
&lt;/h3&gt;&lt;p&gt;原始文档不能直接存进向量库，必须先切成小块（chunk）再存。原因有两个：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一，向量模型有输入长度限制&lt;/strong&gt;，一般最多几百到几千个 token，一篇几千字的文档根本塞不进去。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二，即使模型支持超长输入，把整篇文章压缩成一个向量，细节信息会被&amp;quot;平均掉&amp;quot;。&lt;/strong&gt; 你想找&amp;quot;退款政策&amp;quot;，但向量里还混着&amp;quot;配送时效&amp;quot;&amp;ldquo;积分规则&amp;quot;等内容，最终检索到的是这篇笼统的文档，而不是精确的那段话。&lt;/p&gt;
&lt;p&gt;一篇文档会变成向量库里的多条记录：一篇 5000 字的文档，切成 500 字一个 chunk，就是 10 条记录。每条 chunk 记录包含三个部分，缺一不可：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Chunk 记录结构 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 向量(1024维浮点数) ← 索引卡：用于相似度检索 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 原始文本(chunk内容) ← 书页：LLM真正阅读的内容 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ metadata(来源/页码) ← 书签：用于过滤和溯源 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;可以用一个类比来理解：&lt;strong&gt;向量是索引卡，原文是书页，metadata 是书签&lt;/strong&gt;。索引卡告诉你内容在语义空间的位置，用于快速找到；书页才是 LLM 要读的内容；书签记的是来源文件名、页码，用于过滤和溯源。向量负责&amp;quot;找到&amp;rdquo;，原文负责&amp;quot;阅读&amp;quot;，两者缺一不可。&lt;/p&gt;
&lt;h3 id="22-六种切割策略"&gt;2.2 六种切割策略
&lt;/h3&gt;&lt;p&gt;chunk 大小没有固定答案，通常 500~1000 token 是合理起点，但更重要的是根据文档类型选策略。&lt;/p&gt;
&lt;h4 id="策略一固定大小切割fixed-size-chunking"&gt;策略一：固定大小切割（Fixed Size Chunking）
&lt;/h4&gt;&lt;p&gt;按固定字符数或 token 数切割，不管语义边界在哪。通常会加上&lt;strong&gt;重叠（overlap）&lt;/strong&gt; 来缓解边界截断问题：前一个 chunk 的末尾和下一个 chunk 的开头有一段重叠内容，确保跨边界的语义能被至少一个 chunk 完整覆盖。&lt;/p&gt;
&lt;p&gt;比如 &lt;code&gt;chunk_size=500, overlap=100&lt;/code&gt;，后一个 chunk 的前 100 个字符和前一个 chunk 的后 100 个字符相同。重叠量通常设为 chunk_size 的 10%~20%。太大（如 40%）重复内容太多，干扰 LLM 阅读；太小（如 5%）保护效果弱。&lt;/p&gt;
&lt;p&gt;适合纯文本、无明显结构的文档，是最简单也是最保底的选择。&lt;/p&gt;
&lt;h4 id="策略二语义边界切割semanticstructure-based-chunking"&gt;策略二：语义边界切割（Semantic/Structure Based Chunking）
&lt;/h4&gt;&lt;p&gt;顺着文本的天然断点来切，按段落、句子、标题层级。核心思想：不要在语义中间截断，找到文字天然的&amp;quot;断点&amp;quot;再切。&lt;/p&gt;
&lt;p&gt;句子是语言表达意思的最小完整单位，在句子中间截断就像切断一段话的呼吸。实际操作时维护一个分隔符优先级列表：先按段落切，太大再按句子切，再按标点切，直到满足 chunk_size 限制。&lt;/p&gt;
&lt;p&gt;对有明确标题结构的 Markdown/HTML 文档，按标题层级切更优：每个 chunk 对应一个完整章节，metadata 带上所属标题（如&amp;quot;产品手册 &amp;gt; 退款政策 &amp;gt; 申请流程&amp;quot;），既语义独立又方便溯源。&lt;/p&gt;
&lt;h4 id="策略三特殊内容专项处理"&gt;策略三：特殊内容专项处理
&lt;/h4&gt;&lt;p&gt;代码应该以函数或类为单位切割——一个函数是最小的语义完整单元，从函数中间截断就失去了逻辑意义。用语法解析工具（如 Python 的 AST 模块）识别函数和类的边界。&lt;/p&gt;
&lt;p&gt;表格则要整块保留，转成 Markdown 格式存储，不能按行截断。表格的每一行都依赖表头才有意义，&amp;ldquo;2 小时&amp;quot;单独来看完全不知道是什么的 2 小时，配上列名&amp;quot;响应时间：2 小时&amp;quot;就清晰了。&lt;/p&gt;
&lt;h4 id="策略四父子切割parent-child-chunking"&gt;策略四：父子切割（Parent-Child Chunking）
&lt;/h4&gt;&lt;p&gt;核心思路一句话概括：&lt;strong&gt;检索时用放大镜（小块，精准定位），返回时用全景图（大块，上下文完整）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;存储时同一段内容存两份：细粒度的小 chunk（如 200 token）用于向量检索，语义聚焦、召回精度高；包含上下文的大 chunk（如 1000 token）通过 ID 关联。检索时用小 chunk 找到精准命中点，然后根据关联 ID 取出对应大 chunk 交给 LLM 阅读。&lt;/p&gt;
&lt;p&gt;好比图书馆找书：用目录卡（小 chunk）快速定位到某章某节，但拿出来读的是完整的那一章（大 chunk）。代价是存储量翻倍，但对召回质量要求高的场景值得。&lt;/p&gt;
&lt;h4 id="策略五命题化切割propositions-based-chunking"&gt;策略五：命题化切割（Propositions-based Chunking）
&lt;/h4&gt;&lt;p&gt;不按文本位置切割，而是用 LLM 把文档分解成一条条独立的&amp;quot;命题&amp;rdquo;。每个命题是一个完整、自包含的陈述句，包含了表达这个事实所需的全部上下文，单独拿出来就能看懂。&lt;/p&gt;
&lt;p&gt;原文&amp;quot;企业用户享有优先客服通道，响应时间不超过 2 小时，并可申请专属技术顾问服务&amp;quot;分解成三条独立命题：①企业用户享有优先客服通道。②企业用户的客服响应时间不超过 2 小时。③企业用户可以申请专属技术顾问服务。语义密度极高，检索精度非常好，但需要额外 LLM 调用，成本较高。&lt;/p&gt;
&lt;h4 id="策略六contextual-retrievalanthropic-2024"&gt;策略六：Contextual Retrieval（Anthropic 2024）
&lt;/h4&gt;&lt;p&gt;不改变 chunk 本身，而是在向量化之前把缺失的上下文补进去。让 LLM 看着整篇原始文档，为每个切出来的 chunk 生成一段简短的背景说明（1~2 句话），然后把&amp;quot;Context + chunk&amp;quot;整体做 Embedding。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;原始 chunk: &amp;#34;此条款自 2024年1月1日起生效，适用于所有企业版订阅用户。&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;生成Context: &amp;#34;这段内容说明了企业用户专属客服和技术顾问服务条款的生效日期和适用范围。&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;拼接后向量化: Context + chunk（现在向量里包含了&amp;#34;企业用户&amp;#34;&amp;#34;客服条款&amp;#34;等关键语义）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;借助 Prompt Caching 可把每个 chunk 调 LLM 的成本降低 80%~90%。根据 Anthropic 测评数据，结合 BM25 混合检索能将检索失败率降低约 49%。&lt;/p&gt;
&lt;p&gt;下面是一个用 LangChain 实现递归语义切割的代码示例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.text_splitter&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 递归字符切割：优先按段落切，太大按句子，再按标点&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;splitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 每个 chunk 最多 500 字符&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chunk_overlap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 相邻 chunk 重叠 100 字符，避免语义截断&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;separators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;！&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;；&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;，&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 优先级：段落 &amp;gt; 换行 &amp;gt; 句号 &amp;gt; 感叹号 &amp;gt; 问号 &amp;gt; 分号 &amp;gt; 逗号 &amp;gt; 空格&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;splitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;long_document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;文档被切成 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 个 chunk&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 每个 chunk 语义相对完整，且相邻 chunk 有重叠兜底&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;各策略的适用场景对比：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;策略&lt;/th&gt;
&lt;th&gt;适用文档类型&lt;/th&gt;
&lt;th&gt;优点&lt;/th&gt;
&lt;th&gt;缺点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;固定大小+重叠&lt;/td&gt;
&lt;td&gt;纯文本、无结构&lt;/td&gt;
&lt;td&gt;实现简单、大小可控&lt;/td&gt;
&lt;td&gt;可能在语义中间截断&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;语义边界切割&lt;/td&gt;
&lt;td&gt;段落分明的文章&lt;/td&gt;
&lt;td&gt;语义完整、召回质量好&lt;/td&gt;
&lt;td&gt;实现稍复杂、大小不均&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;特殊内容专项&lt;/td&gt;
&lt;td&gt;代码、表格&lt;/td&gt;
&lt;td&gt;保留逻辑完整性&lt;/td&gt;
&lt;td&gt;需 AST 解析，限定语言&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;父子切割&lt;/td&gt;
&lt;td&gt;追求高质量&lt;/td&gt;
&lt;td&gt;检索精准+上下文完整&lt;/td&gt;
&lt;td&gt;存储翻倍、索引复杂&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;命题化切割&lt;/td&gt;
&lt;td&gt;高质量要求&lt;/td&gt;
&lt;td&gt;语义密度最高&lt;/td&gt;
&lt;td&gt;LLM 调用成本高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Contextual&lt;/td&gt;
&lt;td&gt;语境强场景&lt;/td&gt;
&lt;td&gt;补全孤立 chunk 上下文&lt;/td&gt;
&lt;td&gt;LLM 调用（可缓存降本）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="23-规避语义被切割的方法"&gt;2.3 规避语义被切割的方法
&lt;/h3&gt;&lt;p&gt;语义截断的核心问题不是信息丢了，而是&lt;strong&gt;信息被拆散之后，每一半都不够强，检索时全军覆没&lt;/strong&gt;。规避方法分两个方向：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方向一：切的时候别截断。&lt;/strong&gt; 重叠切割保证跨边界文字不丢失（基础兜底）；语义边界切割顺着句子/段落天然断点切，从根本上避免截断。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方向二：切完之后补上下文。&lt;/strong&gt; 句子窗口检索——存储时切成单句各自向量化，检索命中一个句子后把前后各 N 个句子一起返回；父子切割——小块检索、大块返回；Contextual Retrieval——向量化前为每个 chunk 补全背景上下文。&lt;/p&gt;
&lt;p&gt;另外值得一提的是 &lt;strong&gt;Late Chunking&lt;/strong&gt;（Jina AI 2024 年提出）：传统做法是先切块再编码，每个 chunk 独立过 Embedding 模型，跨块上下文在编码阶段就丢了。Late Chunking 反过来——先让支持长上下文的 Embedding 模型对整篇文档做一次完整前向传播，输出每个 token 的向量（这些 token 向量已通过注意力机制彼此感知），然后按 chunk 边界对同 chunk 内的 token 向量做 mean pooling。先编码后切分，每个 chunk 的向量天然融入全文语境。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;本章实践要点&lt;/strong&gt;：实际工程中通常组合使用——重叠切割做兜底，语义边界切割保证质量，对高质量要求场景再加父子切割或 Contextual Retrieval。chunk_size 起步 500~1000 token，overlap 设 10%~20%。记住：没有银弹，根据文档类型选策略。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第三章embedding-原理与选型"&gt;第三章：Embedding 原理与选型
&lt;/h2&gt;&lt;h3 id="31-从-one-hot-到稠密向量"&gt;3.1 从 one-hot 到稠密向量
&lt;/h3&gt;&lt;p&gt;Embedding 模型做的事情本质上是&amp;quot;语义压缩&amp;quot;——把一段自然语言文本映射成一个固定长度的浮点数向量。这个映射最关键的性质是：&lt;strong&gt;语义相近的文本，向量的余弦相似度高&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;要理解为什么能达到这个效果，需要回顾 Embedding 算法的三代演进。每一代方案解决了一类问题的同时，都暴露出了新的短板——理解&amp;quot;每一代在补上一代的坑&amp;quot;的逻辑，就能理解整个演进脉络。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌────────────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Embedding 算法三代演进 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────┬─────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 第一代: 静态词向量│ Word2Vec / GloVe / FastText (2013) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 每个词固定向量 │ ✓ 解决&amp;#34;词变向量&amp;#34; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 不管上下文 │ ✗ 多义词处理不了（&amp;#34;苹果&amp;#34;=水果=手机） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────┼─────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 第二代: 上下文向量│ ELMo / BERT (2018) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 同词不同向量 │ ✓ 解决多义词 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 需两两拼接 │ ✗ 检索时百万文档跑百万次，不可用 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────┼─────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 第三代: 句子级 │ SBERT / SimCSE / BGE / E5 (2019+) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ bi-encoder独立编码│ ✓ 可提前算好向量存库，查询时只算一次 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 对比学习优化 │ ✗ 精度略低于 cross-encoder │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ → RAG 标配 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────┴─────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第一代：静态词向量（Word2Vec / GloVe / FastText）。&lt;/strong&gt; 核心思路是用一个词周围的词来预测这个词。Word2Vec（Google 2013）有 CBOW 和 Skip-gram 两种训练方式，Skip-gram 更常用，因为它从一个词能产生多个训练样本，对低频词友好。训练完每个词对应一个固定向量，&amp;ldquo;国王 - 男人 + 女人 ≈ 女王&amp;quot;这个著名类比就是 Word2Vec 做到的。GloVe 对全局词共现矩阵做分解；FastText 把词拆成字符级 n-gram 子词，解决了未登录词问题。&lt;/p&gt;
&lt;p&gt;这一代的致命局限是&lt;strong&gt;静态&lt;/strong&gt;：每个词只有一个固定向量，&amp;ldquo;我吃了苹果&amp;quot;和&amp;quot;苹果手机发布了&amp;quot;里的&amp;quot;苹果&amp;quot;向量完全相同。这个缺陷直接催生了第二代。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二代：上下文相关向量（ELMo / BERT）。&lt;/strong&gt; 让词的向量随上下文动态变化。ELMo（2018）用双向 LSTM；BERT（2018）用 Transformer 引入 Masked Language Model，效果全面超越 ELMo。&lt;/p&gt;
&lt;p&gt;但 BERT 在检索场景下有极其致命的缺陷：要比较两个句子相似度，必须把两个句子拼在一起喂给 BERT，让 [CLS] 来判断。这意味着每次检索都要把查询和每一个候选 chunk 拼在一起跑 BERT，百万条文档要跑百万次，一次前向传播几十毫秒，百万次就是好几个小时，用户根本等不起。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三代：句子级对比学习 Embedding（SBERT / SimCSE / BGE）。&lt;/strong&gt; 专门针对&amp;quot;句子相似度&amp;quot;和&amp;quot;语义检索&amp;quot;任务优化，是 RAG 系统的标配。&lt;/p&gt;
&lt;p&gt;SBERT（Sentence-BERT，2019）用 bi-encoder 结构：两个句子分别独立过 BERT，各自得到一个句子级向量，然后用余弦相似度比较。知识库里所有文档的向量可以提前算好存起来，每次检索只算一次查询向量，毫秒级返回。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sentence_transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sklearn.metrics.pairwise&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cosine_similarity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;BAAI/bge-large-zh-v1.5&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查询和文档分别独立编码，不需要拼在一起&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;苹果手机怎么截图&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;iPhone 截屏方法&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;query_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 检索时实时算&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;doc_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 提前算好，存向量库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 余弦相似度衡量语义距离（只看方向不看长度）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cosine_similarity&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;query_vec&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;doc_vec&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# score ≈ 0.95，语义相近但用词完全不同&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;SimCSE（2021）用对比学习把同一句话做两次 dropout 得到两个向量作为正样本对拉近，同 batch 其他句子作为负样本推远，解决了 BERT 原生句子向量的&amp;quot;各向异性&amp;quot;问题（向量分布扭曲、挤在窄小锥形区域）。BGE（北京智源研究院）基于对比学习在大规模中英文数据上训练，同时支持 bi-encoder 和 reranker，是中文 RAG 场景非常流行的开源模型。&lt;/p&gt;
&lt;p&gt;2025-2026 年第三代还在持续进化：&lt;strong&gt;指令感知 Embedding&lt;/strong&gt;（如 Qwen3-Embedding，能根据检索指令动态调整向量表示）；&lt;strong&gt;Matryoshka 表示学习&lt;/strong&gt;（前 N 维就能表达有意义语义，灵活截断维度平衡精度和成本）；&lt;strong&gt;多模态 Embedding&lt;/strong&gt;（同模型编码文本和图片，支持跨模态检索）。&lt;/p&gt;
&lt;h3 id="32-为什么用余弦相似度"&gt;3.2 为什么用余弦相似度
&lt;/h3&gt;&lt;p&gt;衡量向量相似度有欧氏距离和余弦相似度两种。为什么 RAG 里用余弦？&lt;/p&gt;
&lt;p&gt;因为在高维空间里，两段文本的向量长度（模长）会受文本长度、表达强度等非语义因素影响，直接比距离会把&amp;quot;长短&amp;quot;和&amp;quot;语义&amp;quot;混在一起。余弦只看两个向量的方向（夹角），方向越一致余弦值越接近 1，正好把&amp;quot;意思相近&amp;quot;从&amp;quot;文本长短&amp;quot;里剥离出来。可以理解为：两段话如果&amp;quot;指向同一个意思&amp;rdquo;，它们的向量箭头就朝着同一个方向，至于箭头多长无所谓。&lt;/p&gt;
&lt;h3 id="33-embedding-模型选型"&gt;3.3 Embedding 模型选型
&lt;/h3&gt;&lt;p&gt;选模型主要看三个维度：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一，中英文比例。&lt;/strong&gt; 中文为主选 &lt;code&gt;bge-large-zh-v1.5&lt;/code&gt; 或 &lt;code&gt;Qwen3-Embedding&lt;/code&gt;；中英混合选 &lt;code&gt;bge-m3&lt;/code&gt;（支持稠密/稀疏/ColBERT 三种检索模式）；纯英文或追求省事选 &lt;code&gt;text-embedding-3-small&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二，数据合规。&lt;/strong&gt; 数据不能出境就必须用可本地部署的开源模型，BGE 系列和 Qwen3-Embedding 都是很好的选择。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三，向量维度。&lt;/strong&gt; 维度越高精度越好，但存储和检索成本也越大。百万量级知识库 1024 维是合理平衡点；小规模 1536 维也无所谓。新模型支持 Matryoshka 降维可灵活调整。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模型&lt;/th&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;中文效果&lt;/th&gt;
&lt;th&gt;开源&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;text-embedding-3-small&lt;/td&gt;
&lt;td&gt;1536(可降维)&lt;/td&gt;
&lt;td&gt;一般&lt;/td&gt;
&lt;td&gt;否(API)&lt;/td&gt;
&lt;td&gt;英文为主、快速上手&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;text-embedding-3-large&lt;/td&gt;
&lt;td&gt;3072(可降维)&lt;/td&gt;
&lt;td&gt;一般&lt;/td&gt;
&lt;td&gt;否(API)&lt;/td&gt;
&lt;td&gt;英文为主、精度要求高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bge-large-zh-v1.5&lt;/td&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;很好&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;中文知识库经典选择&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bge-m3&lt;/td&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;好&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;中英混合、多语言、多模式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-Embedding&lt;/td&gt;
&lt;td&gt;多种可选&lt;/td&gt;
&lt;td&gt;很好&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;中文场景新一代强力选择&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voyage-3-large&lt;/td&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;一般&lt;/td&gt;
&lt;td&gt;否(API)&lt;/td&gt;
&lt;td&gt;英文高精度检索&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="34-如何评估-embedding-模型"&gt;3.4 如何评估 Embedding 模型
&lt;/h3&gt;&lt;p&gt;一个常见误区：拿 MTEB 通用排行榜分数选模型。MTEB 用通用数据集评测，你的业务场景（医疗问诊、法律文档、客服知识库）和通用数据分布差异很大，排行榜第一不一定适合你。&lt;/p&gt;
&lt;p&gt;正确做法是在&lt;strong&gt;自己的业务数据上测&lt;/strong&gt;：准备几百条&amp;quot;问题 + 正确答案 chunk&amp;quot;对，分别用候选模型做检索，看正确 chunk 有没有出现在前 K 条结果里。这个指标叫 &lt;strong&gt;Hit@K&lt;/strong&gt;——Hit@5 = 0.8 意思是 80% 的问题对应的答案出现在了检索结果前 5 条里。通常 Hit@5 低于 0.7 就要考虑换模型或改进 Chunking 策略。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;本章实践要点&lt;/strong&gt;：中文场景优先评估 &lt;code&gt;bge-large-zh-v1.5&lt;/code&gt; 和 &lt;code&gt;Qwen3-Embedding&lt;/code&gt;；一定要在自有业务数据上跑 Hit@K 测试，别只看排行榜。一旦换 Embedding 模型，整个知识库必须重建——不同模型的向量空间&amp;quot;形状&amp;quot;不同，老向量和新查询不在同一套坐标系里。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第四章向量数据库"&gt;第四章：向量数据库
&lt;/h2&gt;&lt;h3 id="41-为什么需要专门的向量数据库"&gt;4.1 为什么需要专门的向量数据库
&lt;/h3&gt;&lt;p&gt;普通关系型数据库用 B-tree 索引，查询 &lt;code&gt;WHERE id = 123&lt;/code&gt; 这种精确匹配效率极高。但向量检索要做的是找&amp;quot;最相近&amp;quot;的，不是找&amp;quot;等于&amp;quot;的。&lt;/p&gt;
&lt;p&gt;高维向量（如 1024 维）的相似度搜索如果暴力遍历，把查询向量和库里每一条都算一遍余弦相似度，百万条数据要算一百万次，延迟完全不可接受。B-tree 只能处理一维有序索引，对高维向量&amp;quot;多个维度同时要考虑距离&amp;quot;的场景基本失效——你不可能对 1024 维向量建一个 B-tree 然后说&amp;quot;帮我找和它最近的&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;向量数据库的核心价值就是用专门的索引结构把这个搜索加速，在可接受的精度损失下把延迟降到毫秒级。一句话概括：&lt;strong&gt;MySQL 擅长精确匹配（&lt;code&gt;WHERE id=123&lt;/code&gt;），向量数据库擅长语义相似（&amp;ldquo;找和这个意思最接近的内容&amp;rdquo;）&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="42-核心索引算法hnsw-与-ivf"&gt;4.2 核心索引算法：HNSW 与 IVF
&lt;/h3&gt;&lt;p&gt;向量数据库之所以能做到毫秒级检索，秘密全在索引算法上。目前主流有两种：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HNSW（Hierarchical Navigable Small World，分层可导航小世界图）&lt;/strong&gt; 是目前召回率最高的 ANN 算法之一。它构建多层图结构，查询时从最上层稀疏图开始导航，逐层收窄范围，最终在底层找到最近邻。想象在地图上找最近的餐厅：不是把全国所有餐厅遍历一遍，而是先在全国层面找大致方向，再锁定到省、市、区，一层一层缩小。&lt;/p&gt;
&lt;p&gt;HNSW 有两个关键参数：&lt;code&gt;M&lt;/code&gt;（每个节点最多认识几个邻居，通常 16&lt;del&gt;32，越大精度越高但内存越多）和 &lt;code&gt;ef_construction&lt;/code&gt;（建图时考察多少候选，通常 100&lt;/del&gt;200）。查询时还有 &lt;code&gt;ef&lt;/code&gt;（搜索候选集大小，50~200，越大召回越准但延迟越高）。&lt;/p&gt;
&lt;p&gt;优点是召回率高（通常 95%+）、查询速度快；缺点是建索引时内存消耗大。Qdrant、Milvus、Chroma 默认都用 HNSW。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IVF（Inverted File Index，倒排文件索引）&lt;/strong&gt; 是另一种思路：先对向量做聚类，把相似的向量分进同一个&amp;quot;桶&amp;quot;里，查询时只搜最相关的几个桶。就像图书馆分类体系：找编程书先找到&amp;quot;计算机科学&amp;quot;区域，再在里面找，范围大幅缩小。&lt;/p&gt;
&lt;p&gt;优点是内存占用小、适合超大规模；缺点是精度比 HNSW 略低，需要调参（聚类数 nlist、搜索桶数 nprobe）。Milvus 在超大规模场景下用 IVF 系列索引。&lt;/p&gt;
&lt;p&gt;为什么 HNSW 精度高速度快还需要 IVF？因为 HNSW 的内存消耗和向量数量成正比，到了亿级规模内存可能扛不住。IVF 用聚类换内存，牺牲一点精度就能处理超大规模数据，两者各有适用场景。&lt;/p&gt;
&lt;h3 id="43-向量数据库的核心能力"&gt;4.3 向量数据库的核心能力
&lt;/h3&gt;&lt;p&gt;光有 ANN 搜索还不够，生产级系统还要支持几个关键特性：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Metadata 过滤（混合检索）&lt;/strong&gt;：知识库有多个部门、多个产品线的文档，用户只想搜&amp;quot;技术部的文档&amp;quot;或&amp;quot;2024 年更新的内容&amp;quot;。向量数据库支持给每个向量挂 metadata 字段，检索时加过滤条件，只在符合条件子集里做 ANN 搜索。先过滤再 ANN，保证召回的每一条都是真正想要的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实时更新&lt;/strong&gt;：知识库经常需要新增、修改、删除文档，主流向量数据库都支持在线写入，新数据进来后增量构建索引，不需要停服重建。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;与关键词检索融合&lt;/strong&gt;：纯向量检索对精确词语（产品型号、专有名词）效果不好，有些向量数据库同时支持向量检索 + BM25 关键词检索，做混合召回。&lt;/p&gt;
&lt;h3 id="44-主流向量数据库对比"&gt;4.4 主流向量数据库对比
&lt;/h3&gt;&lt;p&gt;选向量数据库主要看三个维度：数据规模、部署方式、是否需要混合检索。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;数据库&lt;/th&gt;
&lt;th&gt;部署方式&lt;/th&gt;
&lt;th&gt;适合规模&lt;/th&gt;
&lt;th&gt;混合检索&lt;/th&gt;
&lt;th&gt;主要优势&lt;/th&gt;
&lt;th&gt;主要劣势&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chroma&lt;/td&gt;
&lt;td&gt;本地/C-S/云&lt;/td&gt;
&lt;td&gt;中小规模&lt;/td&gt;
&lt;td&gt;是(BM25/SPLADE)&lt;/td&gt;
&lt;td&gt;零配置上手极快&lt;/td&gt;
&lt;td&gt;超大规模稳定性待验证&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qdrant&lt;/td&gt;
&lt;td&gt;自托管/云(分布式)&lt;/td&gt;
&lt;td&gt;中大规模(亿级)&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;性能好、API简洁、Rust高性能&lt;/td&gt;
&lt;td&gt;超大规模需调优&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Milvus&lt;/td&gt;
&lt;td&gt;自托管(分布式)&lt;/td&gt;
&lt;td&gt;大规模(亿级)&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;可水平扩展&lt;/td&gt;
&lt;td&gt;部署运维复杂&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pinecone&lt;/td&gt;
&lt;td&gt;全托管云服务&lt;/td&gt;
&lt;td&gt;中大规模&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;无需运维&lt;/td&gt;
&lt;td&gt;费用高、数据出境&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pgvector&lt;/td&gt;
&lt;td&gt;PostgreSQL插件&lt;/td&gt;
&lt;td&gt;中小规模&lt;/td&gt;
&lt;td&gt;是(配合全文检索)&lt;/td&gt;
&lt;td&gt;无需新组件、可JOIN&lt;/td&gt;
&lt;td&gt;性能弱于专用向量库&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;选型建议&lt;/strong&gt;：本地开发用 Chroma 零配置上手；中小到大规模生产推荐 Qdrant（性能好、API 简洁、Docker 一条命令部署）；千万到亿级需分布式选 Milvus（国内大厂用得多，但运维复杂）；不想运维用 Pinecone（注意数据出境）；已有 PostgreSQL 且数据量不大直接用 pgvector 插件。&lt;/p&gt;
&lt;h3 id="45-生产实践性能数据与瓶颈"&gt;4.5 生产实践：性能数据与瓶颈
&lt;/h3&gt;&lt;p&gt;以 Milvus 生产实践为例。知识库约 &lt;strong&gt;150 万条 chunk&lt;/strong&gt;，每条 BGE-large-zh 生成 1024 维向量，HNSW 索引（M=16, ef_construction=128）。&lt;/p&gt;
&lt;p&gt;先算内存：150 万 × 1024 维 × 4 字节(float32) ≈ &lt;strong&gt;6GB&lt;/strong&gt; 纯向量，进程完整跑起来约 10~12GB（含 HNSW 图结构、metadata、管理开销）。开启 &lt;strong&gt;标量量化 SQ8&lt;/strong&gt;（float32 压成 int8，1 字节代替 4 字节）后内存降到约 3GB，召回率基本无损（通常只下降 1 个百分点以内）——这是最划算的优化。&lt;/p&gt;
&lt;p&gt;实测查询性能（单机 16 核 32G、本地千兆网、HNSW 在内存、ef=100）：单次 top-5 查询 &lt;strong&gt;P50 延迟约 20ms，P99 约 60ms&lt;/strong&gt;，并发 100 QPS 延迟基本稳定。&lt;/p&gt;
&lt;p&gt;两个典型瓶颈：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;瓶颈一：内存不足导致查询延迟飙升。&lt;/strong&gt; 8GB 内存机器加载索引后空间很小，稍有权重就频繁 swap，延迟从 20ms 飙到 2s+。解法是开 SQ8 量化，或用 mmap 把原始向量存磁盘只把索引放内存。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;瓶颈二：批量写入触发 Segment 合并，查询抖动。&lt;/strong&gt; 一次性写入几十万条时后台触发 Segment 合并（把增量段合并成封存段并建索引），期间消耗 CPU 和磁盘 IO，P99 延迟从 60ms 涨到 300ms+。解法：时间上错峰（低峰期写入）+ 量上化整为零（每批 500~1000 条，间隔几秒）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Milvus 生产配置示例&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pymilvus&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CollectionSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FieldSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataType&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 定义 Collection Schema&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FieldSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INT64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;is_primary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auto_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FieldSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;embedding&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FLOAT_VECTOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FieldSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;65535&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;# 原文&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FieldSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;source_doc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;# metadata: 来源&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FieldSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;chunk_idx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INT64&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;# metadata: chunk序号&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CollectionSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;RAG知识库&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# HNSW 索引参数（M越大精度越高但内存越多）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;index_params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;index_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HNSW&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;metric_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;COSINE&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;M&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;efConstruction&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查询参数：ef越大召回越准但延迟越高&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;search_params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ef&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;本章实践要点&lt;/strong&gt;：选型从数据规模、部署方式、混合检索三个维度判断。生产环境百万级数据务必开 SQ8 量化省内存；批量写入要错峰+分批，避免 Segment 合并抖动。报性能数字一定带硬件和参数背景——同样的 Milvus，8 核机和 16 核机、ef=100 和 ef=200，数字能差一个量级。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第五章在线检索流程"&gt;第五章：在线检索流程
&lt;/h2&gt;&lt;h3 id="51-为什么不能直接把问题扔给大模型"&gt;5.1 为什么不能直接把问题扔给大模型
&lt;/h3&gt;&lt;p&gt;大模型的上下文窗口有限，不可能把整个知识库塞进去；没有外部知识依据时只靠参数记忆回答容易幻觉。所以 RAG 在线流程本质是一个&amp;quot;精准取件&amp;quot;过程：从海量知识里找到和问题最相关的那几段，再让大模型在小范围里作答。&lt;/p&gt;
&lt;p&gt;用户原始提问的质量决定了后续所有环节的天花板——如果输入就差，后面再怎么精排、再怎么拼 Prompt 都是白搭。所以整个在线流程按顺序分六步，每步都在为下一步准备更好的输入。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ RAG 在线检索六步流程 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 用户提问 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ①Query预处理(改写/HyDE/Step-back/多Query扩展) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 改写后的问题 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ②Query Embedding(必须用和建库相同的模型!) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 问题向量 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ③向量检索(粗排ANN) + 多路召回(BM25并行) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Top-20 候选 chunk │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ④Rerank精排(Cross-Encoder逐对打分) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Top-3~5 高质量 chunk │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ⑤Prompt拼装(资料+问题+约束指令) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 完整 Prompt │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ⑥LLM生成答案 + 引用溯源 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 最终答案(带来源标注) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 耗时分布: Query改写~几十ms | 向量检索~几十ms | │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Rerank~几百ms | LLM生成~1-10s │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="52-第一步query-预处理"&gt;5.2 第一步：Query 预处理
&lt;/h3&gt;&lt;p&gt;用户提问往往口语化、带指代、有歧义，直接检索效果极差。常见技术有四种：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;直接改写&lt;/strong&gt;：让 LLM 把口语化问题转成更正式、独立完整的检索句，补全代词指代。如&amp;quot;上次说的那个退款的事，流程是啥&amp;quot; → &amp;ldquo;申请商品退款的完整操作流程是什么&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HyDE（Hypothetical Document Embeddings）&lt;/strong&gt;：让 LLM 先&amp;quot;假设&amp;quot;一个可能的答案，用假设答案的向量去检索。为什么用答案搜而不是用问题搜？因为问题和答案的用词差异很大，但假设答案和真实答案的用词更接近，它们在语义空间天然更匹配。&amp;ldquo;退款政策是什么&amp;quot;和&amp;quot;申请售后退款须知&amp;quot;距离较远；但假设答案&amp;quot;用户可在购买后14天内申请退款&amp;hellip;&amp;ldquo;和文档距离很近。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step-back Prompting（后退提问）&lt;/strong&gt;：把具体问题往上抽象一层，检索更通用的背景知识。&amp;ldquo;Qdrant 的 HNSW ef 参数设多少合适&amp;rdquo; → &amp;ldquo;HNSW 索引的参数调优原则是什么&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;多 Query 扩展&lt;/strong&gt;：用 LLM 把问题改写成 3~5 个不同角度版本，分别检索后合并去重，覆盖面更广。注意原始问题一定要保留在检索列表里，因为改写过程可能丢失原始细节。&lt;/p&gt;
&lt;h3 id="53-第二步query-向量化"&gt;5.3 第二步：Query 向量化
&lt;/h3&gt;&lt;p&gt;把处理后的问题用 Embedding 模型转成向量。关键细节：&lt;strong&gt;必须用和离线建库时完全相同的 Embedding 模型&lt;/strong&gt;。不同模型的向量空间&amp;quot;形状&amp;quot;不同，模型 A 让&amp;quot;苹果手机&amp;quot;和&amp;quot;iPhone&amp;quot;落在某个方向，模型 B 可能让它们落在另一个方向，连维度数都可能对不上。用 A 建的库用 B 检索，两边的向量就像在不同坐标系里，距离计算毫无意义。&lt;/p&gt;
&lt;h3 id="54-三种检索方式对比"&gt;5.4 三种检索方式对比
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;向量检索（Dense Retrieval）&lt;/strong&gt;：把问题和文档都转成稠密向量，用余弦相似度找最近的 Top-K。擅长语义匹配——&amp;ldquo;苹果手机怎么截图&amp;quot;和&amp;quot;iPhone 如何截屏&amp;quot;一个字不同但余弦相似度可达 0.95。但对精确词语（产品型号、专有名词）效果差。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键词检索（BM25 / Sparse Retrieval）&lt;/strong&gt;：基于词频统计，看查询词在文档里出现了多少次。核心看两个因素：词频 TF（词在文档出现越多越相关）和稀缺度 IDF（词在所有文档里越罕见区分度越高）。BM25 在 TF-IDF 基础上加了饱和度限制防止高频词权重无限叠加。对精确词命中率极高，但遇到同义词就束手无策——&amp;ldquo;手机截图&amp;quot;和&amp;quot;iPhone 截屏&amp;quot;词不重叠，BM25 分数为零。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;混合检索（Hybrid Search）&lt;/strong&gt;：两种方式盲区恰好互补，同时跑两路各召回一批，用 RRF 算法合并。两路可以并行执行，总延迟取两路最大值而非相加。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;关键词检索(BM25)&lt;/th&gt;
&lt;th&gt;向量检索&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;匹配方式&lt;/td&gt;
&lt;td&gt;词汇重叠统计&lt;/td&gt;
&lt;td&gt;语义空间距离&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;索引结构&lt;/td&gt;
&lt;td&gt;倒排索引(稀疏)&lt;/td&gt;
&lt;td&gt;向量库(稠密)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;同义词处理&lt;/td&gt;
&lt;td&gt;无法处理&lt;/td&gt;
&lt;td&gt;天然支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;精确词命中&lt;/td&gt;
&lt;td&gt;极好&lt;/td&gt;
&lt;td&gt;容易漏&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;适合场景&lt;/td&gt;
&lt;td&gt;专有名词、代码、精确查询&lt;/td&gt;
&lt;td&gt;语义问答、模糊表达&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="55-rrf-融合算法"&gt;5.5 RRF 融合算法
&lt;/h3&gt;&lt;p&gt;三路召回各自有排序结果，但分数单位不同（向量是 0~1 余弦值，BM25 是任意正数），没法直接加权平均。RRF（Reciprocal Rank Fusion，互倒排名融合）巧妙绕开了这个问题——不用原始分数，只用排名：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reciprocal_rank_fusion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; results_list: 多路检索结果，每路是一个 [doc_id, ...] 有序列表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; k: 平滑参数，防止排名第1的文档权重过大，通常取 60
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results_list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doc_id&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;doc_id&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;doc_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 排名越靠前（rank越小），倒数越大&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;doc_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 按总分降序排列，取 Top-K&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 使用示例：向量检索和BM25并行召回&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vector_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;doc_a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;doc_b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;doc_c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 向量检索排序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;bm25_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;doc_b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;doc_d&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;doc_a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# BM25排序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;merged&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reciprocal_rank_fusion&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;vector_results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bm25_results&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# doc_b 两路都高排 → 综合分最高&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;RRF 的直觉：不管各路分数怎么算，只看排名。一个文档在多路检索里都排名靠前，综合分就高，就像多位评委都给高分的选手综合排名就高。不需要训练、计算量极小，工程落地成本几乎为零。&lt;/p&gt;
&lt;h3 id="56-第四步rerank-精排"&gt;5.6 第四步：Rerank 精排
&lt;/h3&gt;&lt;p&gt;粗排召回的 Top-20 里可能混入干扰片段。Rerank 用 Cross-Encoder 结构把&amp;quot;query + chunk&amp;quot;拼成一对输入，让模型整体看这一对的相关性，重新打分排序，最终保留 Top-3~5。&lt;/p&gt;
&lt;p&gt;为什么向量检索已经排过序还需要再排？因为两者结构不同：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bi-encoder（向量检索）&lt;/strong&gt;：query 和 chunk 各自独立编码成向量再算余弦相似度。速度快（chunk 向量提前算好存库，查询时只算一次 query 向量），但 query 和 chunk 分开编码，模型看不到两段文字之间的具体词语关联，相关性判断不够精准。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cross-encoder（Rerank）&lt;/strong&gt;：把 query 和 chunk 拼在一起输入，模型能看到 query 中每个词对 chunk 的影响、chunk 里哪些词最能回答 query，相关性判断精度远高于 Bi-encoder。代价是每个候选都要单独跑一次，速度慢，所以只适合小规模候选集精排。&lt;/p&gt;
&lt;p&gt;打个比方：Bi-encoder 像只看两个人简历就判断他们合不合适合作；Cross-encoder 是把两个人放在一个房间里观察他们怎么交流配合，判断当然更准，但代价是需要花更多时间观察每个人。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 使用 BGE-Reranker 做精排&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;FlagEmbedding&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FlagReranker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;reranker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FlagReranker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;BAAI/bge-reranker-v2-m3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;use_fp16&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;苹果手机怎么截图&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;iPhone 截屏操作指南&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 相关&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;安卓手机拍照技巧&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 不相关&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;苹果手机退货政策&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 部分相关&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Cross-Encoder: query 和每个候选拼在一起打分&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pairs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reranker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compute_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# scores: [0.95, 0.12, 0.45] → 重排序后只取 Top-2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;为什么不全用 Cross-encoder 检索？因为它需要两两拼接，百万条数据逐一算分延迟完全不可接受。所以工程上采用&amp;quot;粗排筛到几十条，精排再从几十条里挑最好的几条&amp;quot;的两阶段策略。&lt;/p&gt;
&lt;h3 id="57-prompt-拼装与生成溯源"&gt;5.7 Prompt 拼装与生成溯源
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;你是一个专业助手，请根据以下参考资料回答用户的问题。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;如果参考资料中没有相关信息，请回答&amp;#34;根据现有资料无法回答&amp;#34;，不要自行猜测。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;参考资料：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;[1] &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;chunk_1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;[2] &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;chunk_2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;[3] &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;chunk_3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;用户问题：&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;请在回答中标注信息来源（如&amp;#34;根据资料[1]...&amp;#34;）。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;每条指令都有工程意图：&amp;ldquo;只根据资料回答&amp;quot;抑制 LLM 凭记忆发挥；&amp;ldquo;资料没有就说不知道&amp;quot;防止信息不足时强行补全幻觉；&amp;ldquo;带编号&amp;quot;方便引用溯源，让用户验证答案准确性。&lt;/p&gt;
&lt;p&gt;工程实践中还要求 LLM 在答案里标注每句话来自哪个片段，这样用户可以追溯到原始文档——即使 LLM 在有参考资料时仍可能过度发挥或误读资料，溯源让用户有能力判断哪些内容可靠。&lt;/p&gt;
&lt;p&gt;整个链路耗时分布：Query 改写几十毫秒，向量检索几十毫秒，Rerank 几百毫秒，LLM 生成 1~10 秒。常见优化是缓存高频 Query 检索结果，以及把向量检索和 BM25 检索并行执行。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;本章实践要点&lt;/strong&gt;：Query 预处理是投入产出比很高的一步，口语化提问场景必做；向量检索和 BM25 一定要并行混合检索，覆盖互补；Rerank 是提升精度最直接的手段，强烈推荐；Prompt 必须强约束 LLM 只根据资料回答并标注来源。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第六章检索优化四层框架"&gt;第六章：检索优化四层框架
&lt;/h2&gt;&lt;p&gt;LLM 只能根据送进去的 context 来回答，检索召回的内容就是整个系统的天花板。生成层做得再好，检索没把相关内容找回来，LLM 也是巧妇难为无米之炊。所以 RAG 系统里，&lt;strong&gt;检索优化是投入产出比最高的环节，没有之一&lt;/strong&gt;。RAG 检索优化可以从四个层次来理解，每一层解决的问题不同，优化手段也不同。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ RAG 检索优化四层框架 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌────────────────────────────────────────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 第一层: 索引层(Query层) 知识怎么&amp;#34;存&amp;#34; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Parent-Child / 摘要索引 / 多粒度分层索引 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └────────────────────────────────────────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌────────────────────────────────────────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 第二层: 查询层 问题怎么&amp;#34;转&amp;#34; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Query改写 / HyDE / Step-back / 多Query扩展 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └────────────────────────────────────────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌────────────────────────────────────────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 第三层: 检索层 从哪里&amp;#34;找&amp;#34; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 向量检索 + BM25 + 多Query扩展 → RRF融合 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └────────────────────────────────────────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌────────────────────────────────────────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ 第四层: 结果层 谁&amp;#34;最相关&amp;#34; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ Rerank精排 + 内容压缩 + 上下文窗口控制 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └────────────────────────────────────────────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ (生成层) Prompt约束 + 结构化输出 + 引用溯源 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="61-索引层优化解决检索粒度-vs-上下文完整的矛盾"&gt;6.1 索引层优化：解决检索粒度 vs 上下文完整的矛盾
&lt;/h3&gt;&lt;p&gt;索引优化聚焦于一个核心矛盾：&lt;strong&gt;检索用的粒度和 LLM 读的粒度天然是矛盾的&lt;/strong&gt;。一个 chunk 需要同时完成两个任务——&amp;ldquo;检索时被找到&amp;quot;要求向量语义聚焦（小 chunk），&amp;ldquo;被 LLM 读懂&amp;quot;要求上下文完整（大 chunk）。小 chunk 检索准但内容太碎，大 chunk 内容完整但检索时语义稀释。&lt;/p&gt;
&lt;p&gt;解决思路叫 &lt;strong&gt;Small-to-Big（小块检索、大块使用）&lt;/strong&gt;，有三种实现：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Parent-Child Chunking&lt;/strong&gt;：把文档切成两个版本，细粒度子 chunk（如 150 token）和粗粒度父 chunk（如 500 token），通过 parent_id 关联。入库只给子 chunk 建向量索引；检索用子 chunk 匹配精度高，命中后根据 parent_id 取父 chunk 给 LLM 阅读，上下文完整。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;摘要索引（Summary Index）&lt;/strong&gt;：让 LLM 为每段内容生成摘要，用摘要建向量索引（摘要语义更聚焦，和用户问题更接近），命中后把原始段落塞给 LLM。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;多粒度分层索引&lt;/strong&gt;：同时建章节级、段落级、句子级三层索引。宽泛概念问题用章节级，细节问题用句子级，系统根据问题类型自动选粒度。&lt;/p&gt;
&lt;h3 id="62-查询层优化弥合提问与文档的语义鸿沟"&gt;6.2 查询层优化：弥合提问与文档的语义鸿沟
&lt;/h3&gt;&lt;p&gt;即使索引建得再好，用户提问方式和知识库表述之间还是有鸿沟。用户问&amp;quot;苹果手机咋截图&amp;rdquo;，文档写的是&amp;quot;iPhone 截图操作方法&amp;rdquo;，向量相似度可能不高——口语和书面语在向量空间的&amp;quot;坐标&amp;quot;差距不小，尤其短文本场景下信息量少，表达差异对相似度的影响被放大。&lt;/p&gt;
&lt;p&gt;四种方法已在第五章详述：Query 改写（口语转书面）、多 Query 扩展（多角度撒网）、HyDE（用假设答案搜）、Step-back Prompting（具体问题抽象化检索背景知识）。核心原则：原始问题一定要保留在检索列表里，不能只用改写版本。&lt;/p&gt;
&lt;h3 id="63-检索层优化多路召回互补盲区"&gt;6.3 检索层优化：多路召回互补盲区
&lt;/h3&gt;&lt;p&gt;即使 query 改写得很好，只走一条检索路径还是会漏掉内容。向量检索擅长语义相似但精确词效果差；BM25 擅长精确匹配但同义词无能为力。两种盲区恰好互补，典型三路并行：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;向量检索&lt;/strong&gt;——语义层面覆盖，处理同义词、近义词&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BM25 关键词检索&lt;/strong&gt;——精确词匹配，处理产品型号、专有名词&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多 Query 扩展&lt;/strong&gt;——覆盖不同表述角度，用户提问风格多变时召回覆盖率提升 10%~20%&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;三路结果用 RRF 融合。RRF 最大的优点是实现简单、不需要训练、计算量极小，但融合效果在大多数场景都很好，是多路召回的标配。&lt;/p&gt;
&lt;h3 id="64-结果层优化rerank-精排"&gt;6.4 结果层优化：Rerank 精排
&lt;/h3&gt;&lt;p&gt;多路召回后候选 chunk 可能有 20~30 个，难免混入不太相关的内容。直接全塞给 LLM 有两个问题：一是 token 消耗暴涨成本上升；二是上下文太长 LLM 出现&amp;quot;Lost in the Middle&amp;quot;现象——只关注开头结尾，中间内容被忽略。&lt;/p&gt;
&lt;p&gt;Rerank 用 Cross-encoder 从候选里挑出最相关 3~5 个。常用开源模型有 BGE-Reranker-v2（中英双语效果好）、BCE-Reranker；不想自己部署可用 Cohere Rerank 或 Jina Reranker API。加了 Rerank 后最终答案质量通常有明显提升，是成本效益最高的优化手段之一。&lt;/p&gt;
&lt;h3 id="65-生成层优化prompt-约束"&gt;6.5 生成层优化：Prompt 约束
&lt;/h3&gt;&lt;p&gt;虽然检索层是主战场，生成层也不是完全不用管。Prompt 拼得好不好直接影响 LLM 是否&amp;quot;老实照着资料说&amp;rdquo;。核心约束指令：&amp;ldquo;只能使用参考资料中的信息&amp;rdquo;、&amp;ldquo;资料里没有就说不知道&amp;rdquo;、&amp;ldquo;不要推断和补充&amp;rdquo;、&amp;ldquo;标注信息来源&amp;rdquo;。这些指令每一条都有明确工程意图，缺一不可。&lt;/p&gt;
&lt;h3 id="66-四层怎么组合"&gt;6.6 四层怎么组合
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;层次&lt;/th&gt;
&lt;th&gt;解决的核心问题&lt;/th&gt;
&lt;th&gt;推荐程度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;索引优化(Parent-Child)&lt;/td&gt;
&lt;td&gt;检索粒度vs上下文完整性矛盾&lt;/td&gt;
&lt;td&gt;推荐，效果稳定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查询优化(Multi-Query/HyDE)&lt;/td&gt;
&lt;td&gt;用户提问和知识库表达不对齐&lt;/td&gt;
&lt;td&gt;视场景，提问质量差时必做&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;多路召回(向量+BM25)&lt;/td&gt;
&lt;td&gt;单路检索漏召&lt;/td&gt;
&lt;td&gt;推荐，低成本高收益&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rerank精排&lt;/td&gt;
&lt;td&gt;粗召精度不足&lt;/td&gt;
&lt;td&gt;强烈推荐，提升精度最直接&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一个典型的生产级搭配：&lt;strong&gt;Parent-Child 索引 + 向量 BM25 多路召回 + Rerank 精排&lt;/strong&gt;。这三层组合基本能覆盖大多数场景。如果用户提问质量差再额外加 Query 改写。&lt;/p&gt;
&lt;p&gt;从另一个角度记这四层：&lt;strong&gt;索引层保证&amp;quot;存进去的知识可以被找到&amp;rdquo;，查询层保证&amp;quot;搜索的姿势是对的&amp;rdquo;，召回层保证&amp;quot;不漏掉该找到的内容&amp;rdquo;，Rerank 层保证&amp;quot;送进 LLM 的是真正有用的内容&amp;rdquo;&lt;/strong&gt;。每一层各司其职，组合起来才能把检索质量做到高水准。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;本章实践要点&lt;/strong&gt;：单独优化一个层次往往效果有限，线上系统要组合使用。先靠索引优化和多路召回保证覆盖率，再用 Rerank 保证精度，用户提问质量差时加查询优化。记住主战场永远是检索层，不是换更强的 LLM。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第七章高级-rag-范式"&gt;第七章：高级 RAG 范式
&lt;/h2&gt;&lt;h3 id="71-rag-的三代演进"&gt;7.1 RAG 的三代演进
&lt;/h3&gt;&lt;p&gt;朴素 RAG（Naive RAG）逻辑直白：用户提问 → 向量检索 → 拼 Prompt → LLM 生成。两天能上线 Demo，但什么都没优化——召回什么送什么，用户提问差就找得差，找到内容有没有用也不管，全一股脑塞给 LLM，幻觉和偏差就这样来的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advanced RAG&lt;/strong&gt; 在&amp;quot;检索前&amp;quot;和&amp;quot;检索后&amp;quot;各加一道工序：检索前加 Query 改写和扩展；检索后加 Rerank 精排和内容压缩。不用改框架，只需在原有流程插入几个步骤，工程改动小效果提升明显。目前大多数生产系统用的就是这个形态。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Modular RAG&lt;/strong&gt; 把各环节拆成可独立替换的模块，像乐高一样按需组合：检索模块可选向量/BM25/图检索，改写模块可选 HyDE/Step-back/多 Query，生成模块可选普通输出或带引用结构化输出。LlamaIndex 的 Workflow 和 LangGraph 都是这个思路的实现。&lt;/p&gt;
&lt;p&gt;在这三代之上，还有几个针对特定痛点深度设计的高级范式。&lt;/p&gt;
&lt;h3 id="72-self-ragllm-自主决策检索"&gt;7.2 Self-RAG：LLM 自主决策检索
&lt;/h3&gt;&lt;p&gt;朴素 RAG 不管用户问什么都去检索，但有些问题根本不需要检索（如&amp;quot;1+1等于几&amp;rdquo;），有些检索结果根本不相关。Self-RAG 训练了一个特殊的 LLM，它会自主决定四件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当前问题&lt;strong&gt;需不需要检索&lt;/strong&gt;？（Retrieval token）&lt;/li&gt;
&lt;li&gt;检索回来的内容&lt;strong&gt;相不相关&lt;/strong&gt;？（Relevance token）&lt;/li&gt;
&lt;li&gt;生成的答案&lt;strong&gt;有没有幻觉&lt;/strong&gt;？（Support token）&lt;/li&gt;
&lt;li&gt;最终答案&lt;strong&gt;质量够不够好&lt;/strong&gt;？（Utility token）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;执行流程：判断是否需要检索 → 不需要的常识问题直接回答 → 需要的检索后逐条评估相关性，不相关跳过 → 每个相关 chunk 各自生成候选答案 → 评估每个答案有没有文档支撑和对用户有没有用 → 综合打分选出最优答案返回。&lt;/p&gt;
&lt;p&gt;关键前提：这四种 reflection token 不是现成 LLM 自带的，需要在专门构造的数据集上对基础 LLM 做监督微调。所以 Self-RAG 不能拿普通 GPT-4 直接&amp;quot;套用&amp;rdquo;——要么用论文开源的微调版本（基于 Llama2），要么自己造数据微调。这是它和 CRAG、Agentic RAG 很不一样的地方，后者都可以在通用 LLM 上直接跑。&lt;/p&gt;
&lt;h3 id="73-crag检索质量差时自动纠错降级"&gt;7.3 CRAG：检索质量差时自动纠错降级
&lt;/h3&gt;&lt;p&gt;Self-RAG 解决&amp;quot;要不要检索&amp;quot;的问题，那检索了但结果质量很差怎么办？CRAG（Corrective RAG）在检索完之后加了质量评估环节：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ CRAG 三级路由决策 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 本地检索 Top-K chunk │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 轻量级检索评估器(打分) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ┌────┼────────────┬──────────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ▼ ▼ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ &amp;#34;相关&amp;#34; &amp;#34;模糊&amp;#34; &amp;#34;不相关&amp;#34; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ▼ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 直接用 本地+网络 丢弃本地结果 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 本地结果 合并使用 降级走网络搜索 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 生成答案 生成答案 用搜索结果生成 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;核心价值在于&amp;quot;兜底&amp;quot;：知识库覆盖不到的问题不会直接乱答，而是自动去网上找答案。它把知识库当主力，把网络搜索当备胎，两者配合使用，大幅提升系统健壮性。评估器可以是专门训练的分类模型，也可以用 Rerank 模型的分数近似。判断阈值需根据业务调，经验值在 0.3~0.6 之间。&lt;/p&gt;
&lt;h3 id="74-graphrag用知识图谱增强全局理解"&gt;7.4 GraphRAG：用知识图谱增强全局理解
&lt;/h3&gt;&lt;p&gt;传统 RAG 有三个硬伤：&lt;strong&gt;跨文档多跳推理干不了&lt;/strong&gt;（&amp;ldquo;A 公司的投资方和 B 公司有什么交集&amp;quot;需要跨多文档做关系推理）、&lt;strong&gt;全局性问题答不上&lt;/strong&gt;（&amp;ldquo;这份财报的核心观点是什么&amp;quot;需要通读归纳而非检索 Top-K）、&lt;strong&gt;切块带来语义断裂&lt;/strong&gt;（实体间因果关系被切断）。&lt;/p&gt;
&lt;p&gt;这三个痛点的根本原因：&lt;strong&gt;传统 RAG 做的是&amp;quot;找相似文本&amp;rdquo;，但企业需要的是&amp;quot;理解实体关系&amp;rdquo;&lt;/strong&gt;。GraphRAG（微软 2024 年 4 月）的解法是——用 LLM 把文档&amp;quot;读成一张知识图谱&amp;quot;，然后基于图谱做检索和回答。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;索引阶段 5 步：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ GraphRAG 索引阶段(离线，一次性) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 原始文档 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ①文档切块(Text Unit) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 文本块们 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ②LLM实体关系提取(每块调一次LLM) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 实体节点 + 关系边 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ③生成实体/关系摘要(汇总同一实体的多处描述) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 带综合描述的图 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ④社区检测(Leiden算法，层次化划分) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 多层社区(Level0粗→Level3细) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ ⑤生成社区摘要(每个社区调LLM写报告) │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 知识图谱 + 层次化社区报告 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ⚠️ Token消耗巨大: 1M token约$20-50，是传统RAG的几十倍 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;以《三国演义》为例：Level 0 划成&amp;quot;曹魏集团&amp;quot;&amp;ldquo;蜀汉集团&amp;quot;&amp;ldquo;东吴集团&amp;quot;等大社区；Level 1 在&amp;quot;蜀汉集团&amp;quot;里分出&amp;quot;刘关张小团体&amp;quot;&amp;ldquo;诸葛亮周边&amp;quot;&amp;ldquo;五虎上将&amp;rdquo;；一路细分到无法再拆。每个社区都有一份 LLM 生成的摘要报告——这就是 GraphRAG 回答全局问题的核心资产。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;查询阶段两种模式：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Local Search（本地搜索）&lt;/strong&gt;：适用具体实体问题（&amp;ldquo;A 公司的 CTO 是谁&amp;rdquo;）。先用问题向量在实体节点向量索引里找入口实体，沿图边扩展到邻居实体、关系、原始文本块、所属社区报告，组装上下文交给 LLM。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Global Search（全局搜索）&lt;/strong&gt;：适用全局性问题（&amp;ldquo;整本书讲了哪几派势力斗争&amp;rdquo;）。用 Map-Reduce 策略：Map 阶段把某层级所有社区报告分批让 LLM 生成中间答案并打重要性评分；Reduce 阶段汇总中间答案按评分排序合并成最终答案。一次 Global Search 端到端延迟常在 10 秒到 1 分钟之间——因为要遍历几百上千个社区，每个都要调 LLM。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GraphRAG 的四大难点：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;索引成本高得吓人（Token 焚烧炉）&lt;/strong&gt;：每个文本块调 LLM 抽实体，每个实体/关系调 LLM 合成描述，每个社区调 LLM 写报告。100 万 token 索引成本 $20-50，传统 RAG 只要几美分，差三四个数量级。给 5GB 法律文档建索引成本可能高达 3.3 万美元。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实体消歧&lt;/strong&gt;：LLM 抽取天然不一致——&amp;ldquo;IBM&amp;quot;&amp;ldquo;国际商业机器&amp;quot;&amp;ldquo;Big Blue&amp;quot;被抽成多个节点，导致知识图谱被&amp;quot;近重复节点&amp;quot;塞满，关系碎片化，40% 相关合同挂在另一个节点下查不出来。业界没有标准解法，需叠加字符串编辑距离+向量相似度+LLM 判别+人工兜底。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;查询延迟&lt;/strong&gt;：Global Search 的 Map-Reduce 遍历大量社区，10s-1min 延迟，C 端实时交互不可能用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;增量更新牵一发而动全身&lt;/strong&gt;：新文档进来可能触发实体消歧→图结构变→社区划分过时→社区摘要全部失效→向量索引同步更新。很多团队只能定期全量重建，成本问题被放大。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="75-lightraggraphrag-的轻量化改良"&gt;7.5 LightRAG：GraphRAG 的轻量化改良
&lt;/h3&gt;&lt;p&gt;LightRAG（香港大学 2024 年 10 月）就是为了解决 GraphRAG 这些痛点而生，设计哲学是&amp;quot;Simple&amp;quot;和&amp;quot;Fast&amp;rdquo;。三个核心创新：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;创新一：图增强文本索引（去社区化）。&lt;/strong&gt; 和 GraphRAG 一样用 LLM 抽实体和关系，但&lt;strong&gt;根本不做社区检测，也不做社区摘要&lt;/strong&gt;——Leiden 算法和最烧钱的 LLM 调用全省掉了。只保留实体节点 + 关系边这个最核心的图结构，描述向量化存进向量库。仅这两步就省了 80% 以上的 LLM 调用量。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;创新二：双层检索范式。&lt;/strong&gt; 不做社区摘要了，全局问题怎么答？LightRAG 的做法是在查询时把查询拆成两层关键词：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;查询: &amp;#34;国际贸易如何影响全球经济稳定？&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LLM抽取:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; high_level_keywords: [&amp;#34;国际贸易&amp;#34;, &amp;#34;全球经济稳定&amp;#34;, &amp;#34;经济影响&amp;#34;] ← 抽象主题
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; low_level_keywords: [&amp;#34;贸易协定&amp;#34;, &amp;#34;关税&amp;#34;, &amp;#34;货币汇率&amp;#34;, &amp;#34;进出口&amp;#34;] ← 具体对象
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Low-level检索: 用低层关键词搜实体节点 → 找&amp;#34;点&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;High-level检索: 用高层关键词搜关系边 → 找&amp;#34;线&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;两路并行 → 合并组装上下文 → LLM生成答案
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;一路找&amp;quot;点&amp;rdquo;（具体实体），一路找&amp;quot;线&amp;rdquo;（关系主题），两种信息合起来组装上下文。不用预先生成社区摘要，每次查询只调一次 LLM 做关键词抽取 + 几次向量检索。相比 GraphRAG 的 Map-Reduce 全局查询，&lt;strong&gt;查询成本和延迟降了一个数量级&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;创新三：增量更新算法。&lt;/strong&gt; 本质就是&amp;quot;追加&amp;quot;两字。新文档来了跑实体关系抽取，直接 upsert 到图和向量库。同名实体合并描述，新实体加新节点。&lt;strong&gt;完全没有&amp;quot;社区&amp;quot;这层，自然没有&amp;quot;社区失效&amp;quot;问题&lt;/strong&gt;，增量索引变得跟传统 RAG 一样轻。&lt;/p&gt;
&lt;p&gt;LightRAG 还有个小巧思——&lt;strong&gt;关系关键词&lt;/strong&gt;：抽取关系时额外生成一个描述这条关系主题的关键词（如&amp;quot;张三创立 A 公司&amp;rdquo;→ 关键词&amp;quot;创业、企业创立&amp;rdquo;），这就是后面&amp;quot;高层检索&amp;quot;命中相关关系的钥匙。&lt;/p&gt;
&lt;h3 id="76-四大范式详细对比"&gt;7.6 四大范式详细对比
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;对比维度&lt;/th&gt;
&lt;th&gt;Self-RAG&lt;/th&gt;
&lt;th&gt;CRAG&lt;/th&gt;
&lt;th&gt;GraphRAG(微软)&lt;/th&gt;
&lt;th&gt;LightRAG(港大)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;核心创新&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LLM自主决策检索&lt;/td&gt;
&lt;td&gt;检索质量差时降级网络搜索&lt;/td&gt;
&lt;td&gt;社区检测+社区摘要&lt;/td&gt;
&lt;td&gt;双层检索+增量友好&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;解决痛点&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;不是所有问题都需检索&lt;/td&gt;
&lt;td&gt;知识库覆盖不全&lt;/td&gt;
&lt;td&gt;全局理解+跨文档关联&lt;/td&gt;
&lt;td&gt;GraphRAG成本/增量/延迟&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;索引成本&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无特殊索引&lt;/td&gt;
&lt;td&gt;无特殊索引&lt;/td&gt;
&lt;td&gt;极高(Token焚烧炉)&lt;/td&gt;
&lt;td&gt;低(减少99%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;查询延迟&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;正常&lt;/td&gt;
&lt;td&gt;正常+网络搜索&lt;/td&gt;
&lt;td&gt;慢(Global可达分钟级)&lt;/td&gt;
&lt;td&gt;快(秒级)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;增量更新&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;正常&lt;/td&gt;
&lt;td&gt;正常&lt;/td&gt;
&lt;td&gt;难(级联复杂)&lt;/td&gt;
&lt;td&gt;易(直接追加)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;全局深度洞察&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;强(社区摘要)&lt;/td&gt;
&lt;td&gt;一般(临场组装)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;工程复杂度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;高(需特殊训练模型)&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;模型要求&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;需微调特殊LLM&lt;/td&gt;
&lt;td&gt;通用LLM即可&lt;/td&gt;
&lt;td&gt;通用LLM即可&lt;/td&gt;
&lt;td&gt;通用LLM即可&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="77-选型建议什么时候用什么"&gt;7.7 选型建议：什么时候用什么
&lt;/h3&gt;&lt;p&gt;一个务实的决策思路：&lt;strong&gt;不要一上来就选重型方案&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据 &amp;lt; 10 万 token&lt;/strong&gt;：传统 RAG 就够了，没必要上图&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;10 万 ~ 500 万 token&lt;/strong&gt;：LightRAG 最佳甜蜜区&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;需要深度全局洞察且预算管够&lt;/strong&gt;：GraphRAG&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;问题类型多样、部分不需检索&lt;/strong&gt;：Self-RAG&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;知识库覆盖不全需兜底&lt;/strong&gt;：CRAG&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最常见的混合架构：对稳定的、历史性核心知识（公司规章、法规库）用 GraphRAG 建索引做深度分析；对动态的日常变化数据（工单、新闻、产品更新）用 LightRAG 实时响应；查询时搭一个 Query Router 根据查询类型分流到对应系统。&lt;/p&gt;
&lt;p&gt;一句话总结：&lt;strong&gt;GraphRAG 是深度分析的重型武器，LightRAG 是日常使用的轻巧刀具&lt;/strong&gt;。大多数企业 RAG 落地用 LightRAG 就能覆盖 80% 需求，剩下 20% 深度分析再上 GraphRAG 补充。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;本章实践要点&lt;/strong&gt;：选高级范式前先用传统 RAG 搭 MVP，跑一段时间看用户到底在问什么类型的问题。如果大量问题涉及跨文档关系、全局主题，再升级到 LightRAG；如果 LightRAG 也搞不定高精度深度分析，才上 GraphRAG。RAG 技术发展本质上是在&amp;quot;精度&amp;quot;&amp;ldquo;成本&amp;quot;&amp;ldquo;速度&amp;quot;&amp;ldquo;维护&amp;quot;之间不断做权衡，没有银弹。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第八章rag-生产落地"&gt;第八章：RAG 生产落地
&lt;/h2&gt;&lt;h3 id="81-幻觉规避"&gt;8.1 幻觉规避
&lt;/h3&gt;&lt;p&gt;很多人以为做了 RAG 就不会有幻觉了，这是常见误区。塞进 prompt 不等于 LLM 一定&amp;quot;老老实实照着说&amp;rdquo;。RAG 里的幻觉有两个完全不同的来源：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;检索层幻觉&lt;/strong&gt;：检索没召回到相关内容，LLM 没有可用上下文，靠自身知识编造答案。你的知识库记录退款政策是&amp;quot;7 天无理由退款&amp;rdquo;，但某次检索没召回到这个 chunk，LLM 用自己的&amp;quot;知识&amp;quot;给出&amp;quot;30 天退款&amp;rdquo;——用户按这个操作退款失败。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;生成层幻觉&lt;/strong&gt;：检索到了相关 chunk，但 LLM 没有严格遵循，在文档内容基础上加了自己的推断、补充了原文没有的细节、甚至把两段不相关的信息混在一起。读者很难分辨哪句来自文档、哪句是 LLM 加的。&lt;/p&gt;
&lt;p&gt;四个递进的规避方案：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方案一：Prompt 强约束（成本最低）&lt;/strong&gt;。明确立规矩：只能用参考资料中的信息、资料里没有就说不知道、回答时标注来源、不要推断和补充。这几条规则让 LLM&amp;quot;知道自己的边界&amp;rdquo;，给了它&amp;quot;合法的逃生出口&amp;quot;。能压制生成层幻觉，但对检索层幻觉帮助有限。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方案二：检索质量门控&lt;/strong&gt;。Rerank 模型对每个候选打 0&lt;del&gt;1 分，最高分低于阈值就直接拒答&amp;quot;知识库无相关信息，建议联系人工&amp;quot;，不让 LLM 在低质量上下文硬撑。阈值需按业务数据调，经验值 0.3&lt;/del&gt;0.6，精度要求高（金融医疗）偏高。方案一+方案二是上线前基础配置。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方案三：生成后引用核查&lt;/strong&gt;。LLM 生成完答案，再用另一个 LLM 回头检查每条关键信息在 chunk 里有没有依据，没依据的标注&amp;quot;无法核实&amp;quot;或删掉。代价是多一次 LLM 调用，延迟和成本翻倍，只用于医疗问诊、法律咨询等容错率极低场景。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方案四：结构化输出强制溯源&lt;/strong&gt;。让 LLM 输出 JSON，每个结论必须填来自哪条参考资料的编号。LLM 构建 JSON 时必须主动想&amp;quot;这条结论从哪条资料找到的&amp;quot;，这个过程本身就会减少瞎编概率——就像让学生写论文必须标参考文献，他自然不敢随便编。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;answer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;完整回答&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;statements&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;claim&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;具体结论1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;source_ids&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;claim&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;具体结论2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;source_ids&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;confidence&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;high&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;核心认知：&lt;strong&gt;检索质量是幻觉的最大来源&lt;/strong&gt;。检索到了正确内容，Prompt 再稍微约束，幻觉就已经少很多了；检索这一步就烂，再多的生成层约束也填不了坑。&lt;strong&gt;治幻觉，先治检索。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="82-评估体系"&gt;8.2 评估体系
&lt;/h3&gt;&lt;p&gt;靠&amp;quot;用户投诉&amp;quot;或&amp;quot;人工抽查&amp;quot;评估是亡羊补牢。RAG 评估要把&amp;quot;好不好&amp;quot;这个主观感受拆解成可追踪、可对比、可指导决策的客观数字，分两层：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;检索层评估&lt;/strong&gt;——不管 LLM 输出，只看该召回的有没有召回到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hit@K&lt;/strong&gt;：Top-K 结果里有没有正确 chunk。Hit@5=0.8 意思是 80% 问题的答案出现在前 5 条。低于 0.7 说明检索层有问题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MRR（平均倒数排名）&lt;/strong&gt;：关心正确 chunk 排第几名。第一名得 1 分，第二名 0.5 分，第三名 0.33 分。低于 0.5 说明 Rerank 效果不够好。简单记：&lt;strong&gt;Hit@K 是&amp;quot;找到没&amp;quot;，MRR 是&amp;quot;多快找到的&amp;quot;&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;生成层评估（RAGAs 框架）&lt;/strong&gt;——用 LLM 当裁判（LLM-as-a-Judge）自动打分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Faithfulness（忠实度）&lt;/strong&gt;：答案每件事在 chunk 里有没有出处？衡量幻觉程度。目标 &amp;gt; 0.8。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Answer Relevancy（答案相关性）&lt;/strong&gt;：答案有没有回答用户问的问题？和 Faithfulness 是两回事——可以字字有据但完全跑题。目标 &amp;gt; 0.8。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context Recall（上下文召回率）&lt;/strong&gt;：回答所需信息有多少比例在检索结果里覆盖到？低说明检索漏了关键信息。目标 &amp;gt; 0.7。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context Precision（上下文精确率）&lt;/strong&gt;：检索结果里有用内容排名是否靠前？低说明召回太多噪音。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过指标组合精确定位问题：Context Recall 低 → 换更强 Embedding 或调 Chunking 或加多路召回；Context Precision 低 → 加强 Rerank；Faithfulness 低 → 加强 Prompt 约束或检索质量门控；Answer Relevancy 低 → Prompt 指令不够明确。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;线上指标&lt;/strong&gt;才是最终验收标准：点踩率（最直接负反馈）、追问率（答非所问程度）、转人工率（RAG 放弃回答频率）、空回答率（系统说&amp;quot;不知道&amp;quot;的比例）、会话解决率（最综合指标）。形成&amp;quot;离线测评→上线→线上观测→发现问题→离线复现→修复→再上线&amp;quot;的闭环。&lt;/p&gt;
&lt;h3 id="83-动态更新"&gt;8.3 动态更新
&lt;/h3&gt;&lt;p&gt;RAG 知识库更新不能像普通数据库直接 UPDATE。因为原始文档和向量库之间是一对多关系——一篇文档被切成几十上百个 chunk，文档内容变了切割结果可能完全不同，chunk 数量、边界、内容都会变。&lt;/p&gt;
&lt;p&gt;最可靠的更新逻辑是&lt;strong&gt;先删后增&lt;/strong&gt;：把旧文档对应的所有 chunk 全部删掉，重新按新内容切割入库。不要尝试&amp;quot;局部更新&amp;quot;——文档一改切割边界就变了，没法把旧 chunk 和新 chunk 一一对应打补丁。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;变更检测&lt;/strong&gt;用内容 hash：每次入库算 MD5/SHA256，和存储的 hash 对比。相同跳过，不同触发重处理。优化：先用&amp;quot;最后修改时间&amp;quot;粗筛，只对时间戳变化的才算 hash，能过滤 99% 未变文档。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;chunk ID 设计&lt;/strong&gt;很关键：让 chunk ID 带文档 ID 前缀（如 &lt;code&gt;product_manual_v3_chunk_001&lt;/code&gt;），或在 metadata 存 &lt;code&gt;source_doc_id&lt;/code&gt; 字段，这样删除一篇文档所有 chunk 时能批量查找删除。&lt;strong&gt;从一开始就把文档和 chunk 的关联关系设计好&lt;/strong&gt;，等到需要更新时再临时想办法会很狼狈。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;两种变更感知方式&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;定时轮询（Polling）&lt;/strong&gt;：固定间隔扫描对比 hash。实现简单不依赖外部系统，但有延迟，适合更新频率低的场景。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;事件驱动（Event-Driven）&lt;/strong&gt;：数据源变更时通过 Kafka/RabbitMQ/Webhook 发消息，收到立刻处理。延迟低（秒级），适合客服知识库、新闻资讯等实时性要求高场景。很多 CMS（Confluence、Notion、语雀）支持 Webhook，天然适合事件驱动。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;灰度更新&lt;/strong&gt;用于核心生产知识库：不直接删旧数据，先把新版本 chunk 打 &lt;code&gt;version=new&lt;/code&gt; 标签并行写入，旧版本保留 &lt;code&gt;version=old&lt;/code&gt;。验证阶段用测试问题同时跑新旧版本对比，确认无退化后把检索版本过滤条件从 old 切到 new，最后清理旧版本。类似蓝绿部署，出问题可秒级回滚。&lt;/p&gt;
&lt;p&gt;生产环境推荐&amp;quot;事件驱动 + hash 变更检测 + 先删后增&amp;quot;的组合方案。全量重建只在两种情况用：知识库规模很小（几十篇几分钟搞定）；或做了重大架构调整（换 Embedding 模型、改 Chunking 策略，新旧向量不兼容）。&lt;/p&gt;
&lt;h3 id="84-rag-落地三大难点"&gt;8.4 RAG 落地三大难点
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;第一难：文档预处理。&lt;/strong&gt; 这是最前面一环，做不好后面所有优化都难救回来——给系统喂的原料是烂的。难在现实世界文档格式五花八门：PDF 的表格、双栏、嵌套排版被通用库解析成乱码（pypdf 做的是文本流提取，表格应交给 pdfplumber/unstructured）；扫描版需 OCR；含图片的文档关键信息提取不到；代码块切割不当破坏逻辑完整性。真正的生产系统文档预处理代码量往往比 RAG 核心逻辑还多。进去的是垃圾，出来的也是垃圾。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二难：检索质量调优。&lt;/strong&gt; 检索质量是系统天花板，但问题来源很多，排查费劲。Chunking 策略不当——退款相关内容被切散在十几个 chunk 里每个都不够强；Query 和文档语义鸿沟——口语提问和正式文档用词差距大；向量检索对精确词效果差——产品型号不如 BM25。这三个问题交织在一起，定位起来特别麻烦。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三难：效果评估。&lt;/strong&gt; 单条答案对错人工判断成本高且标准不统一；端到端指标反馈周期太长，出了问题不知道是 Chunking 的锅还是检索的锅还是 LLM 生成的锅。没有量化指标体系就不知道该优化哪里，优化变成瞎猜。必须建立检索层（Hit@K + MRR）+ 生成层（RAGAs）+ 线上指标的分层评估体系。&lt;/p&gt;
&lt;p&gt;总结一句话：&lt;strong&gt;原型 Demo 一两天能跑起来，但把它调到生产可用的质量水平，往往需要几周甚至几个月的迭代。&lt;/strong&gt; 每个环节都可以是瓶颈，而且各环节相互影响，没有捷径。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;本章实践要点&lt;/strong&gt;：幻觉规避先治检索（方案一+方案二上线前必做）；评估体系分检索层和生成层两层，必须在自有业务数据上跑；动态更新用&amp;quot;事件驱动+hash检测+先删后增&amp;quot;，chunk ID 设计从一开始做好；文档预处理别用通用库硬解 PDF 表格，该上专项工具就上。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="结尾"&gt;结尾
&lt;/h2&gt;&lt;h3 id="核心知识点回顾"&gt;核心知识点回顾
&lt;/h3&gt;&lt;p&gt;让我们用一张表快速回顾本文的全部核心知识点：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;章节&lt;/th&gt;
&lt;th&gt;核心知识点&lt;/th&gt;
&lt;th&gt;一句话记忆&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;第一章&lt;/td&gt;
&lt;td&gt;RAG 本质&lt;/td&gt;
&lt;td&gt;给 LLM &amp;ldquo;开卷考试&amp;rdquo;，知识存外部实时检索，不改模型参数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第一章&lt;/td&gt;
&lt;td&gt;三大问题&lt;/td&gt;
&lt;td&gt;知识时效性 + 私有知识覆盖 + 幻觉，根源都是知识冻结在参数里&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第一章&lt;/td&gt;
&lt;td&gt;vs 微调&lt;/td&gt;
&lt;td&gt;微调解决&amp;quot;怎么说&amp;quot;，RAG 解决&amp;quot;说什么&amp;quot;，可组合使用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第二章&lt;/td&gt;
&lt;td&gt;文档切割&lt;/td&gt;
&lt;td&gt;不能整篇存，500~1000 token 起步，按文档类型选策略&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第二章&lt;/td&gt;
&lt;td&gt;六种策略&lt;/td&gt;
&lt;td&gt;固定大小/语义边界/特殊内容/父子/命题化/Contextual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第二章&lt;/td&gt;
&lt;td&gt;规避截断&lt;/td&gt;
&lt;td&gt;切时别截断(重叠+语义边界) + 切完补上下文(窗口/父子/Contextual)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第三章&lt;/td&gt;
&lt;td&gt;三代演进&lt;/td&gt;
&lt;td&gt;静态词向量→上下文向量→句子级对比学习(RAG标配)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第三章&lt;/td&gt;
&lt;td&gt;选型评估&lt;/td&gt;
&lt;td&gt;中文 BGE/Qwen3，一定要在业务数据上跑 Hit@K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第四章&lt;/td&gt;
&lt;td&gt;索引算法&lt;/td&gt;
&lt;td&gt;HNSW 精度高内存大，IVF 内存小精度略低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第四章&lt;/td&gt;
&lt;td&gt;选型&lt;/td&gt;
&lt;td&gt;中小用 Qdrant，亿级用 Milvus，已用 PG 用 pgvector&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第四章&lt;/td&gt;
&lt;td&gt;生产实践&lt;/td&gt;
&lt;td&gt;百万级开 SQ8 量化省内存，批量写入要错峰分批&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第五章&lt;/td&gt;
&lt;td&gt;六步流程&lt;/td&gt;
&lt;td&gt;Query预处理→向量化→粗排+多路→Rerank→拼Prompt→生成溯源&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第五章&lt;/td&gt;
&lt;td&gt;三种检索&lt;/td&gt;
&lt;td&gt;向量(语义)+BM25(精确词)+混合(互补)，RRF融合&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第五章&lt;/td&gt;
&lt;td&gt;Rerank&lt;/td&gt;
&lt;td&gt;Cross-encoder 比 bi-encoder 准但慢，只对小候选集精排&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第六章&lt;/td&gt;
&lt;td&gt;四层框架&lt;/td&gt;
&lt;td&gt;索引层→查询层→检索层→结果层，组合使用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第七章&lt;/td&gt;
&lt;td&gt;Self-RAG&lt;/td&gt;
&lt;td&gt;LLM 自主决策要不要检索，需微调特殊模型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第七章&lt;/td&gt;
&lt;td&gt;CRAG&lt;/td&gt;
&lt;td&gt;检索质量差时降级网络搜索兜底&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第七章&lt;/td&gt;
&lt;td&gt;GraphRAG&lt;/td&gt;
&lt;td&gt;社区检测+摘要支持全局查询，但贵慢难增量&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第七章&lt;/td&gt;
&lt;td&gt;LightRAG&lt;/td&gt;
&lt;td&gt;去社区化+双层检索+增量友好，成本降99%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第八章&lt;/td&gt;
&lt;td&gt;幻觉规避&lt;/td&gt;
&lt;td&gt;治幻觉先治检索，Prompt约束+质量门控是基础配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第八章&lt;/td&gt;
&lt;td&gt;评估体系&lt;/td&gt;
&lt;td&gt;检索层 Hit@K+MRR，生成层 RAGAs，线上点踩率/转人工率&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第八章&lt;/td&gt;
&lt;td&gt;动态更新&lt;/td&gt;
&lt;td&gt;事件驱动+hash检测+先删后增，chunk ID 从一开始设计好&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第八章&lt;/td&gt;
&lt;td&gt;三大难点&lt;/td&gt;
&lt;td&gt;文档预处理(垃圾进垃圾出)+检索调优(多环节交织)+效果评估&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="主题关联"&gt;主题关联
&lt;/h3&gt;&lt;p&gt;本文是「AI 大模型工程知识体系」系列的第 02 篇，与系列其他篇章紧密关联：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;与第 01 篇（LLM 基础）的关联&lt;/strong&gt;：RAG 的存在前提是 LLM 的&amp;quot;知识冻结&amp;quot;特性——LLM 训练完知识就固化在参数里，这是第一章三大问题的根源。理解 LLM 的预训练机制（预测下一个词、无&amp;quot;不知道&amp;quot;开关），才能理解为什么 RAG 是解决幻觉最有效的方案。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;与 Agent 篇章的关联&lt;/strong&gt;：第七章的 Agentic RAG 把 RAG 嵌入 Agent 循环——LLM 自主决定要不要再检索一次、用什么关键词、检索结果是否充分。这是 RAG 向 Agent 演进的关键节点，GraphRAG 和 LightRAG 也可以作为 Agent 的工具被动态调用。Agent 框架（LangGraph、LlamaIndex Workflow）正是 Modular RAG 思想的具体实现。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;与向量检索/数据库篇章的关联&lt;/strong&gt;：第四章的向量数据库是 RAG 的基础设施，HNSW 和 IVF 索引算法的理解深度直接决定了生产环境的性能调优能力。如果后续有专门的向量检索深入篇章，本文提供了 RAG 场景的应用上下文。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="进一步阅读"&gt;进一步阅读
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;GraphRAG 论文&lt;/strong&gt;：Darren Edge 等，《From Local to Global: A Graph RAG Approach to Query-Focused Summarization》（微软，2024.4）——理解社区检测+层次摘要的原始设计。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LightRAG 论文&lt;/strong&gt;：Zirui Guo 等，《LightRAG: Simple and Fast Retrieval-Augmented Generation》（港大，2024.10，EMNLP 2025 Findings）——理解双层检索和增量友好的轻量化设计。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Self-RAG 论文&lt;/strong&gt;：Akari Asai 等，《Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection》——理解 reflection token 的微调机制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CRAG 论文&lt;/strong&gt;：Shi-Qi Yan 等，《Corrective Retrieval Augmented Generation》——理解三级路由降级策略。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contextual Retrieval&lt;/strong&gt;：Anthropic 官方技术博客（2024）——理解向量化前补全上下文的方案及 Prompt Caching 降本实践。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAGAs 框架&lt;/strong&gt;：Shahul Es 等，《RAGAS: Automated Evaluation of Retrieval Augmented Generation》——理解 LLM-as-a-Judge 的评估方法论。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MTEB 排行榜&lt;/strong&gt;：Hugging Face 上的文本 Embedding 通用排行榜，选型参考但不可盲信，务必在业务数据上验证。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Late Chunking&lt;/strong&gt;：Jina AI 博客（2024）——理解先编码后切分如何保留跨块上下文。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;RAG 技术的发展，本质上是在&amp;quot;精度&amp;quot;&amp;ldquo;成本&amp;quot;&amp;ldquo;速度&amp;quot;&amp;ldquo;维护&amp;quot;之间不断做权衡。没有银弹，只有最适合你业务场景的方案。把基础打牢，后面的进阶技术学起来就会事半功倍。&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;系列导航&lt;/strong&gt;：&lt;a class="link" href="./00_%e5%af%bc%e8%ae%ba_AI%e5%a4%a7%e6%a8%a1%e5%9e%8b%e5%b7%a5%e7%a8%8b%e7%9f%a5%e8%af%86%e4%bd%93%e7%b3%bb%e6%80%bb%e8%a7%88.md" &gt;← 上一篇：00 导论&lt;/a&gt; ｜ [下一篇：Agent 智能体 →]&lt;/p&gt;</description></item><item><title>大模型基础与工程化实践</title><link>https://blog.irudder.me/ai/ai-systematization/01-Foundation-of-Large-Models-and-Engineering-Practice.html</link><pubDate>Fri, 24 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/ai-systematization/01-Foundation-of-Large-Models-and-Engineering-Practice.html</guid><description>&lt;h1 id="大模型基础与工程化实践"&gt;大模型基础与工程化实践
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;本文是&amp;quot;AI 知识体系&amp;quot;系列的开篇，系统梳理大语言模型从底层原理到工程落地的完整知识链路。定位是：让初学者理解 LLM 的本质，让有经验者加深对底层原理的理解。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="核心问题列表"&gt;核心问题列表
&lt;/h2&gt;&lt;p&gt;在深入正文之前，先列出本文要回答的 8 个核心问题。如果你能对每一个都给出有深度的回答，说明你对大模型工程化已经有了扎实的理解：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;为什么&amp;quot;预测下一个 token&amp;quot;这个看似简单的训练目标，能造就一个能写代码、解数学题、创作诗歌的通用智能模型？&lt;/strong&gt; 它和传统 NLP&amp;quot;一任务一模型&amp;quot;的范式区别到底在哪？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Self-Attention 为什么要用 Q/K/V 三个矩阵，而不是直接用输入本身？&lt;/strong&gt; 公式里那个 &lt;code&gt;/√d_k&lt;/code&gt; 到底在防止什么？为什么 Decoder-only 架构最终胜出？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MHA、MQA、GQA、Flash Attention 这四者是什么关系？&lt;/strong&gt; 它们是替代还是叠加？为什么主流大模型都是&amp;quot;GQA + Flash Attention&amp;quot;一起用？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;为什么主流大模型几乎全部选择了 RoPE 而不是 sin/cos 或 ALiBi？&lt;/strong&gt; 绝对位置编码和相对位置编码的本质差异是什么？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;大模型训练为什么要分&amp;quot;预训练 → SFT → 对齐&amp;quot;三个阶段，缺一不可？&lt;/strong&gt; Chinchilla 的 1:20 比例为什么被 Llama 3 的 1:1875 打破了？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LoRA 除了&amp;quot;省参数&amp;quot;，还有哪些被低估的优点？&lt;/strong&gt; 为什么它能成为 PEFT 的事实标准，把 Adapter 等早期方案完全淘汰？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RLHF、DPO、GRPO、拒绝采样、RLAIF 这五种 Post-Training 方法是什么关系？&lt;/strong&gt; 为什么 DeepSeek R1 让 GRPO 火遍整个圈子？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;KV Cache 和 Prompt Caching 是同一个东西吗？&lt;/strong&gt; 量化时 GPTQ、AWQ、NF4 各自的核心创新是什么？MoE 为什么能&amp;quot;学得多 + 跑得快&amp;quot;？&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="引言为什么理解大模型底层原理对-ai-工程至关重要"&gt;引言：为什么理解大模型底层原理对 AI 工程至关重要
&lt;/h2&gt;&lt;p&gt;很多人第一次接触大模型，是从&amp;quot;调用 OpenAI API&amp;quot;开始的。在他们的认知里，大模型是一个黑盒——输入一段文字，输出一段文字，中间发生了什么不重要，只要效果够好就行。&lt;/p&gt;
&lt;p&gt;这种&amp;quot;工具使用者&amp;quot;的视角在原型阶段没问题，但一旦进入真正的工程化阶段，就会处处碰壁：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;为什么同样的 Prompt，换一个模型效果就差很多？&lt;/strong&gt; 因为你不理解不同模型的架构差异（Dense vs MoE）、训练阶段差异（有没有做过 RLHF）、上下文处理方式差异（用什么位置编码、支持多长上下文）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;为什么长上下文场景下显存爆了？&lt;/strong&gt; 因为你不理解 KV Cache 的显存占用规律，不知道 GQA 和 Flash Attention 是怎么省显存的，也不会评估该用什么量化方案。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;为什么微调后模型&amp;quot;变笨了&amp;quot;？&lt;/strong&gt; 因为你不理解灾难性遗忘的机制，不知道 LoRA 为什么能缓解它，更不知道微调的目标（SFT/DPO）和方法（全量/LoRA/QLoRA）是两个正交维度。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;为什么模型一本正经地胡说八道，Temperature 调到 0 也止不住？&lt;/strong&gt; 因为你不理解幻觉的根因——LLM 本质是&amp;quot;按概率续写&amp;quot;不是&amp;quot;查询数据库&amp;quot;，温度只能减少随机偏差，不能修正记忆错误。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;为什么排行榜上第一的模型，用到自己业务里反而不行？&lt;/strong&gt; 因为你不理解数据污染问题，也没有建立自己的业务测试集，更没有从&amp;quot;合规、成本、延迟、能力&amp;quot;四个维度做选型。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些问题的共性是：&lt;strong&gt;它们都不是&amp;quot;调 API&amp;quot;能解决的，必须回到底层原理去理解。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;大模型工程和传统软件工程有一个根本区别：传统软件的行为是确定性的、可预测的，你写什么样的代码就得到什么样的结果；而大模型是概率性的、涌现的，它的行为由训练数据、模型架构、训练目标、推理参数共同决定，任何一个环节理解不到位，都会导致线上事故。&lt;/p&gt;
&lt;p&gt;这就是为什么理解底层原理对 AI 工程至关重要。它不是&amp;quot;学术修养&amp;quot;，而是&amp;quot;工程能力&amp;quot;——决定了你能不能把大模型从&amp;quot;Demo 能跑&amp;quot;推进到&amp;quot;生产可用&amp;quot;。&lt;/p&gt;
&lt;p&gt;本文将带你从 LLM 的本质出发，逐层深入到 Transformer 架构、注意力优化、位置编码、分词器、训练全景、微调与对齐、推理优化、Prompt 工程、部署与评测，构建一张完整的知识地图。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第一章大语言模型的本质"&gt;第一章：大语言模型的本质
&lt;/h2&gt;&lt;h3 id="11-llm-与传统-nlp-模型的根本区别"&gt;1.1 LLM 与传统 NLP 模型的根本区别
&lt;/h3&gt;&lt;p&gt;要理解大语言模型&amp;quot;大&amp;quot;在哪里，得先看看在它之前，业界是怎么处理自然语言任务的。&lt;/p&gt;
&lt;p&gt;传统 NLP 的工作方式是&amp;quot;流水线&amp;quot;式的，一个完整任务要拆成好几个独立步骤，每一步用一个专门的模型来完成。以智能客服为例：第一步分词，把&amp;quot;我想退货&amp;quot;拆成&amp;quot;我 / 想 / 退货&amp;quot;；第二步词性标注，标出&amp;quot;我&amp;quot;是代词、&amp;ldquo;退货&amp;quot;是动词；第三步命名实体识别，找出有没有商品名、订单号；第四步意图分类，判断这是&amp;quot;咨询&amp;quot;还是&amp;quot;投诉&amp;rdquo;；第五步去知识库匹配预设答案。&lt;/p&gt;
&lt;p&gt;这种 pipeline 又长又脆。光是&amp;quot;分词&amp;quot;这一步就有一堆坑——中文不像英文有空格天然分隔，&amp;ldquo;南京市长江大桥&amp;quot;到底是&amp;quot;南京市/长江大桥&amp;quot;还是&amp;quot;南京/市长/江大桥&amp;rdquo;？这种歧义靠规则解决不了，必须有一个专门的分词模型来判断。而分词模型本身又依赖大量人工标注语料，遇到训练时没见过的新词（比如&amp;quot;奥利给&amp;quot;&amp;ldquo;绝绝子&amp;rdquo;），它就懵了，这就是著名的 &lt;strong&gt;OOV（Out-of-Vocabulary，未登录词）&lt;/strong&gt; 问题。&lt;/p&gt;
&lt;p&gt;每一步都有独立的痛点，每一步都得有自己的模型、自己的训练数据。前面一步错了后面全错，错误会&lt;strong&gt;累积传导&lt;/strong&gt;。更糟糕的是迁移成本——换个领域，所有模型基本都得重新训练。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;任务越细分，模型越多；模型越多，标注成本越高；标注越贵，迁移越难。&lt;/strong&gt; 整个 NLP 行业都被困在这个死循环里。&lt;/p&gt;
&lt;p&gt;2018 年 BERT 的出现打破了第一次僵局。BERT 的核心创新是&lt;strong&gt;预训练 + 微调&lt;/strong&gt;两阶段范式：在海量无标注文本上做 MLM（掩码语言模型），学到通用语言表示，然后在下游任务上接一个小&amp;quot;任务头&amp;quot;微调。这一招把 NLP 各项任务的 SOTA 刷了个遍。&lt;/p&gt;
&lt;p&gt;但 BERT 走到一半就停了。它解决了&amp;quot;特征通用&amp;quot;但没解决&amp;quot;任务统一&amp;quot;——不同任务还是要不同的微调副本、不同的任务头。而且 BERT 是判别式的，不擅长生成。&lt;/p&gt;
&lt;p&gt;LLM 最根本的转变，是把所有 NLP 任务统一成了一件事：&lt;strong&gt;预测下一个 token&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;传统 NLP&lt;/th&gt;
&lt;th&gt;LLM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;任务方式&lt;/td&gt;
&lt;td&gt;一任务一模型，pipeline 串联&lt;/td&gt;
&lt;td&gt;一个模型干所有事，Prompt 统一接口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;输出范式&lt;/td&gt;
&lt;td&gt;判别式（输出标签/概率）&lt;/td&gt;
&lt;td&gt;生成式（输出文本）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;能力来源&lt;/td&gt;
&lt;td&gt;显式监督训练（喂什么学什么）&lt;/td&gt;
&lt;td&gt;大规模预训练 + 涌现（学到没教过的能力）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这张表的三行，分别从&amp;quot;工程层面&amp;quot;&amp;ldquo;范式层面&amp;quot;&amp;ldquo;能力层面&amp;quot;刻画了同一个变化的不同侧面。工程层面，团队结构从&amp;quot;N 个小模型组各管一摊&amp;quot;变成&amp;quot;一个大模型组统一服务&amp;rdquo;；范式层面，从&amp;quot;分类器思维&amp;quot;切换到&amp;quot;生成器思维&amp;rdquo;；能力层面，模型可以做&amp;quot;人没明确教过&amp;quot;的任务——这在整个 NLP 历史上是前所未有的事。&lt;/p&gt;
&lt;h3 id="12-预测下一个-token为什么威力如此之大"&gt;1.2 &amp;ldquo;预测下一个 token&amp;quot;为什么威力如此之大
&lt;/h3&gt;&lt;p&gt;这个训练目标叫 &lt;strong&gt;CLM（Causal Language Modeling，因果语言模型）&lt;/strong&gt;。训练数据格式特别简单：给一段文本，模型从左到右一个字一个字地往后猜，每一步都预测&amp;quot;下一个 token 是什么&amp;rdquo;。比如训练数据是&amp;quot;我喜欢吃苹果&amp;quot;，模型要学会：看到&amp;quot;我&amp;quot;预测&amp;quot;喜&amp;quot;，看到&amp;quot;我喜&amp;quot;预测&amp;quot;欢&amp;quot;，看到&amp;quot;我喜欢&amp;quot;预测&amp;quot;吃&amp;quot;，依此类推。&lt;/p&gt;
&lt;p&gt;听起来太简单了，但威力极大。看几个例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;翻译&lt;/strong&gt;：Prompt 写&amp;quot;把下面这句翻译成英文：我喜欢你 -&amp;gt;&amp;quot;，LLM 接着预测下一个 token，就会输出&amp;quot;I like you&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分类&lt;/strong&gt;：Prompt 写&amp;quot;下面这条评论是正面还是负面？&amp;lsquo;这家店太黑了&amp;rsquo; -&amp;gt; 答：&amp;quot;，LLM 预测下一个 token 就会输出&amp;quot;负面&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;总结&lt;/strong&gt;：Prompt 写&amp;quot;请用一句话总结：xxxxxx -&amp;gt; 总结：&amp;quot;，LLM 接着写下去就是总结&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;写代码&lt;/strong&gt;：Prompt 写&amp;quot;写一个 Python 函数，返回斐波那契数列前 N 项 -&amp;gt; def&amp;quot;，LLM 接着续写就是完整代码&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所有任务都被&amp;quot;Prompt + 续写&amp;quot;这个统一接口收编了。你不需要为每个任务训不同的模型，只需要在 Prompt 里换个说法。&lt;/p&gt;
&lt;p&gt;那为什么这个简单目标能学到这么多东西？关键是&lt;strong&gt;规模 + 数据&lt;/strong&gt;两个杠杆。&lt;/p&gt;
&lt;p&gt;数据的杠杆是：CLM 不需要任何人工标注，互联网上所有文本天然都是合格的训练数据。GPT-3 用了 3000 亿 token，Llama 3 用了 15 万亿 token，这种规模在 BERT 时代是不可想象的。&lt;/p&gt;
&lt;p&gt;模型的杠杆是：参数量从 BERT 的 0.3B 一路堆到 GPT-3 的 175B，再到后来更大的模型。模型要在不同上下文里准确预测，就必须学到语法、事实和推理模式。要预测&amp;quot;北京是中国的____&amp;ldquo;的下一个词，模型必须知道&amp;quot;北京是首都&amp;quot;这个事实；要预测&amp;quot;如果 x=2，那么 x²=____&amp;quot;，模型必须会算数。所有这些能力，都被&amp;quot;预测下一个 token&amp;quot;这个目标&lt;strong&gt;逼着学会了&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;还有一个让人惊讶的副产物，叫 &lt;strong&gt;In-Context Learning（上下文学习）&lt;/strong&gt;。在 Prompt 里给模型几个例子，模型就能学会新的任务模式，不需要更新参数：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;苹果 -&amp;gt; apple
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;香蕉 -&amp;gt; banana
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;草莓 -&amp;gt; strawberry
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;橘子 -&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;模型看到这个 Prompt，不需要任何额外训练，就能输出&amp;quot;orange&amp;rdquo;。它从几个例子里推出了&amp;quot;中译英水果名&amp;quot;这个模式。这种能力是 GPT-3 之后才被业界发现的，也是 Prompt Engineering 这门工程学科诞生的基础。&lt;/p&gt;
&lt;h3 id="13-自回归生成的数学直觉"&gt;1.3 自回归生成的数学直觉
&lt;/h3&gt;&lt;p&gt;LLM 的生成方式叫&lt;strong&gt;自回归（Autoregressive）&lt;/strong&gt;，意思是&amp;quot;下一步的预测依赖上一步的输出&amp;quot;。数学上可以写成：&lt;/p&gt;
&lt;p&gt;$$P(x_1, x_2, &amp;hellip;, x_n) = \prod_{i=1}^{n} P(x_i \mid x_1, x_2, &amp;hellip;, x_{i-1})$$&lt;/p&gt;
&lt;p&gt;即整个序列的概率等于每一步条件概率的乘积。每生成一个新 token，模型都会输出一个 vocabulary 大小（典型 5 万到 15 万）的概率分布，告诉你&amp;quot;下一个 token 是各个词的可能性&amp;quot;，然后按某种解码策略选一个 token，拼到上下文后面，循环直到结束。&lt;/p&gt;
&lt;p&gt;这里有一个朴素实现隐藏的巨大低效：如果每次都从头算所有 token 的 attention，N 个 token 的总计算量是 O(N³)。KV Cache 的出现把这个问题解决了（详见第九章），但理解自回归的本质——&lt;strong&gt;每一步只依赖前一步的输出，逐步展开&lt;/strong&gt;——是理解后续 KV Cache、推理优化、解码策略的基础。&lt;/p&gt;
&lt;h3 id="14-规模与数据两个杠杆"&gt;1.4 规模与数据两个杠杆
&lt;/h3&gt;&lt;p&gt;LLM 还有一个让传统 NLP 模型望尘莫及的特点，叫&lt;strong&gt;涌现能力（Emergent Abilities）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;涌现的常见定义是：&amp;quot;&lt;strong&gt;某项能力在小模型上几乎看不到，规模到了某个临界点之后突然表现出来&lt;/strong&gt;&amp;quot;。典型例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;多步算术&lt;/strong&gt;：参数量 8B 以下准确率几乎为 0；62B 约 5%；540B（PaLM）突然跳到 60%&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In-Context Learning&lt;/strong&gt;：1.5B 的 GPT-2 完全看不到，175B 的 GPT-3 突然就有了，临界点在 100B 左右&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨语言迁移&lt;/strong&gt;：GPT-3 训练数据 92% 是英文，但训完能直接处理中文、阿拉伯语甚至冰岛语&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为什么会涌现？业界给出的工程经验叫 &lt;strong&gt;Scaling Law（缩放定律）&lt;/strong&gt;。简单说就是模型规模、训练数据量、训练算力这三者之间存在一种可预测的关系：你把这三个量按一定比例同时放大，模型的损失值会沿着一条幂律曲线下降。这个经验律 OpenAI 在 2020 年提出，DeepMind 后来在 Chinchilla 论文里给出了更精细的比例（详见第六章）。&lt;/p&gt;
&lt;p&gt;不过要注意 2023 年斯坦福的 &lt;em&gt;Are Emergent Abilities of Large Language Models a Mirage?&lt;/em&gt; 论文的挑战：很多&amp;quot;涌现&amp;quot;可能只是&amp;quot;评估指标的不连续性&amp;quot;造成的测量假象，换成连续指标曲线就平滑了。学术争议还在继续，但工程层面，模型规模带来的能力跃迁是客观存在的。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点：&lt;/strong&gt; 理解 LLM 的本质是&amp;quot;用海量语料预训练、参数到百亿千亿规模、自回归生成文本的统一模型&amp;quot;。三个本质区别（任务统一、生成式、涌现）分别从工程、范式、能力三个层面刻画了它与传统 NLP 的不同。做 LLM 项目时，工作方式从&amp;quot;先拆任务再选模型&amp;quot;变成了&amp;quot;先想 Prompt 怎么写&amp;quot;，这是范式转变的直接体现。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第二章transformer-架构深度剖析"&gt;第二章：Transformer 架构深度剖析
&lt;/h2&gt;&lt;h3 id="21-self-attention-的数学原理"&gt;2.1 Self-Attention 的数学原理
&lt;/h3&gt;&lt;p&gt;2017 年 Google 在论文《Attention is All You Need》里提出了 Transformer，用一个全新的架构一举解决了 RNN 的两个老问题：顺序计算无法并行、长距离梯度消失。&lt;/p&gt;
&lt;p&gt;Self-Attention（自注意力）的核心思路是：让序列中的每个 token 都能&lt;strong&gt;直接关注&lt;/strong&gt;序列中任意其他位置的 token，计算出&amp;quot;我和其他位置的相关程度&amp;quot;，然后根据相关程度加权聚合其他位置的信息。&lt;/p&gt;
&lt;p&gt;这里有三个关键向量：&lt;strong&gt;Q（Query，查询）&lt;/strong&gt; 代表&amp;quot;我想找什么&amp;quot;，&lt;strong&gt;K（Key，键）&lt;/strong&gt; 代表&amp;quot;我有什么标签&amp;quot;，&lt;strong&gt;V（Value，值）&lt;/strong&gt; 代表&amp;quot;我的实际内容&amp;quot;。&lt;/p&gt;
&lt;p&gt;可以用图书馆检索来类比：你有一个搜索关键词（Q），图书馆里每本书都有标签（K）和内容（V）。注意力机制就是用你的关键词（Q）去匹配每本书的标签（K），计算出相似度分数，然后按照分数的权重把书的内容（V）加权求和，得到你的搜索结果。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q/K/V 是怎么从输入变换得到的？&lt;/strong&gt; 这是理解 Self-Attention 的关键一步。Q/K/V 不是模型&amp;quot;凭空生成&amp;quot;的，而是把输入 embedding 通过&lt;strong&gt;三个独立的线性投影矩阵&lt;/strong&gt; W_Q、W_K、W_V 算出来的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 假设输入 X 是 (序列长度 N, embedding 维度 d_model)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# W_Q, W_K, W_V 都是可训练参数矩阵，形状 (d_model, d_k)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="n"&gt;W_Q&lt;/span&gt; &lt;span class="c1"&gt;# 形状 (N, d_k)，每个 token 都有自己的 Query 向量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;K&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="n"&gt;W_K&lt;/span&gt; &lt;span class="c1"&gt;# 形状 (N, d_k)，每个 token 都有自己的 Key 向量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;V&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="n"&gt;W_V&lt;/span&gt; &lt;span class="c1"&gt;# 形状 (N, d_v)，每个 token 都有自己的 Value 向量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;几个关键点要抓住：&lt;/p&gt;
&lt;p&gt;最关键的是 Q/K/V 都是&lt;strong&gt;从同一个输入 X 算出来&lt;/strong&gt;的——输入既要扮演&amp;quot;提问者&amp;quot;（Q），也要扮演&amp;quot;被查者&amp;quot;（K + V），这就是&amp;quot;&lt;strong&gt;自&lt;/strong&gt;注意力&amp;quot;里那个&amp;quot;自&amp;quot;字的含义。&lt;/p&gt;
&lt;p&gt;W_Q、W_K、W_V 是三个&lt;strong&gt;独立学习&lt;/strong&gt;的矩阵。如果让 Q/K/V 都直接等于 X 不做变换，模型就没法学到&amp;quot;该从什么角度提问&amp;quot;&amp;ldquo;该用什么标签匹配&amp;quot;这种细致差异。三个独立投影让模型有 3 倍的自由度去学习角度上的差异。&lt;/p&gt;
&lt;p&gt;投影维度 d_k 通常等于 d_model / H（H 是头数），目的是让多头总参数量和单头版本基本一致。&lt;/p&gt;
&lt;p&gt;代入注意力公式：&lt;/p&gt;
&lt;p&gt;$$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{Q \cdot K^T}{\sqrt{d_k}}\right) \cdot V$$&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;为什么要除以 √d_k？&lt;/strong&gt; 这个常被叫做 &lt;strong&gt;Scaled Dot-Product Attention（缩放点积注意力）&lt;/strong&gt;。当 d_k 很大时（比如 128），Q 和 K 都是 128 维向量，点积是 128 个数相加。假设每维都是均值 0、方差 1 的随机数，点积方差就是 d_k=128，标准差约 11.3。这意味着点积数值会散布在 -30 到 +30 的范围，过 softmax 后最大的那个数对应概率接近 1、其他接近 0，&lt;strong&gt;输出几乎变成 one-hot 分布&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;one-hot 分布的问题是&lt;strong&gt;梯度消失&lt;/strong&gt;——softmax 的梯度公式里有 &lt;code&gt;p · (1-p)&lt;/code&gt; 项，p 接近 0 或 1 时梯度都接近 0。除以 √d_k 后，点积方差被压回 1，softmax 输出分布合理，梯度能正常传播。这是被 8 年实践验证的&amp;quot;简单且数学上合理&amp;quot;的选择。&lt;/p&gt;
&lt;h3 id="22-为什么-self-attention-优于-rnncnn"&gt;2.2 为什么 Self-Attention 优于 RNN/CNN
&lt;/h3&gt;&lt;p&gt;Transformer 之前，处理序列数据的主流是 RNN（循环神经网络）及其变体（LSTM、GRU）。RNN 有两个致命缺陷：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一，顺序计算，无法并行。&lt;/strong&gt; RNN 从左到右逐个处理每个词，第 N 步必须等第 N-1 步算完才能开始，无法利用 GPU 并行。训练大型 RNN 极慢。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二，长距离梯度消失。&lt;/strong&gt; 序列很长时（比如 1000 个词），梯度在反向传播时指数级衰减，网络很难学习&amp;quot;第 1 个词和第 800 个词之间的关系&amp;rdquo;。LSTM 门控机制有所缓解，但根本问题没解决。&lt;/p&gt;
&lt;p&gt;Self-Attention 一举解决了这两个问题：整个过程对序列中所有位置的计算可以&lt;strong&gt;并行&lt;/strong&gt;（所有 token 的 Q/K/V 一次性算出），而且每对位置之间都有&lt;strong&gt;直接连接&lt;/strong&gt;（通过注意力分数），不存在长距离信息衰减。&lt;/p&gt;
&lt;h3 id="23-encoder-vs-decoder为什么-decoder-only-架构胜出"&gt;2.3 Encoder vs Decoder：为什么 Decoder-only 架构胜出
&lt;/h3&gt;&lt;p&gt;理解了 Attention 的基本机制，可以解释三种架构的区别：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Encoder-only（以 BERT 为代表）&lt;/strong&gt;：每个 token 可以双向关注所有其他 token。擅长&amp;quot;理解任务&amp;quot;（分类、NER、语义相似度）。预训练目标是 MLM（掩码语言模型）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Decoder-only（以 GPT/Claude/Qwen 为代表）&lt;/strong&gt;：使用因果掩码（Causal Mask），每个 token 只能关注它前面的 token。天然适合文本生成。预训练目标是 CLM（预测下一个 token）。现在几乎所有大语言模型都是这个架构。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Encoder-Decoder（以 T5、BART 为代表）&lt;/strong&gt;：Encoder 双向理解输入，Decoder 单向生成输出，通过 Cross-Attention 读取 Encoder 的输出。适合翻译、摘要等&amp;quot;输入输出不同&amp;quot;的任务。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;为什么 Decoder-only 赢了？&lt;/strong&gt; 根本原因是&amp;quot;预测下一个 token&amp;quot;这个目标极其统一。所有类型的任务（问答、写作、推理、代码、翻译）都可以统一表达成&amp;quot;续写&amp;quot;这一件事。更关键的是，这个目标可以直接在海量无标注文本上做自监督训练，不需要逐条人工标注。最厉害的是，随着规模增大，这个简单目标下涌现出的能力越来越强。&lt;/p&gt;
&lt;h3 id="24-多头注意力的意义"&gt;2.4 多头注意力的意义
&lt;/h3&gt;&lt;p&gt;单组 Q/K/V 只能学习到一种&amp;quot;关联关系&amp;quot;，但语言中的关联是多维度的：&amp;ldquo;我&amp;quot;和&amp;quot;吃&amp;quot;是主谓关系，&amp;ldquo;苹果&amp;quot;和&amp;quot;吃&amp;quot;是宾动关系，&amp;ldquo;苹果&amp;quot;和前文的&amp;quot;苹果树&amp;quot;是指代关系。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Multi-Head Attention&lt;/strong&gt; 把 Q/K/V 投影到多个不同的子空间（比如 8 个或 32 个头），每组独立计算注意力，最后把所有头的输出拼接起来。每个头可以专注于捕捉不同类型的语言关联，整体上表达能力更强。&lt;/p&gt;
&lt;p&gt;除了注意力层，每个 Transformer 块里还有一个前馈网络（FFN），结构是两层全连接加激活函数。FFN 对每个位置独立做非线性变换，补充注意力层学不到的信息（注意力层本质是线性加权，FFN 引入非线性）。研究表明 &lt;strong&gt;FFN 层储存了大量的&amp;quot;事实知识&amp;rdquo;&lt;/strong&gt;，可以理解为模型的&amp;quot;记忆仓库&amp;rdquo;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点：&lt;/strong&gt; 理解 Transformer，最重要的是讲清 RNN 卡在哪两点、Self-Attention 怎么破、为什么 Decoder-only 赢。Q/K/V 是从同一个 X 通过三个独立矩阵投影得到的，除以 √d_k 是防止 softmax 变 one-hot 导致梯度消失。Decoder-only 胜在&amp;quot;目标统一 + 数据规模 + 涌现&amp;quot;的组合。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第三章注意力优化演进"&gt;第三章：注意力优化演进
&lt;/h2&gt;&lt;h3 id="31-mha-的局限性"&gt;3.1 MHA 的局限性
&lt;/h3&gt;&lt;p&gt;要讲清楚 MHA（Multi-Head Attention）的局限，得先把&amp;quot;训练&amp;quot;和&amp;quot;推理&amp;quot;两个阶段分开看。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;训练阶段&lt;/strong&gt;：每一层 Attention 都要算一个 N×N 的注意力分数矩阵 &lt;code&gt;softmax(QK^T/√d) · V&lt;/code&gt;。N=32K 时这个矩阵膨胀到 10 亿个数（FP16 约 2GB），计算复杂度 O(N²)。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推理阶段&lt;/strong&gt;：LLM 自回归生成，每次生成一个新 token 都要重新对前面所有 token 算注意力。如果每次从头算，成本累加成 O(N³)。聪明的做法是 &lt;strong&gt;KV Cache&lt;/strong&gt;：把前面所有 token 的 K 和 V 矩阵存下来，每次新 token 只算自己的 Q。但 KV Cache 本身就是个显存大户：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;KV Cache 显存 = 2（K和V各一份）× B（batch）× N（序列长）× L（层数）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; × H（头数）× d_k（每头维度）× 2 字节（FP16）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;对一个 7B 模型（L=32、H=32、d_k=128），跑 batch=1、N=32K：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2 × 1 × 32000 × 32 × 32 × 128 × 2 ≈ 17 GB
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;光 KV Cache 就 17GB，加上模型权重 14GB，总共 31GB，一张 4090（24GB）根本放不下。&lt;/p&gt;
&lt;p&gt;还有更隐蔽的痛点是&amp;rdquo;&lt;strong&gt;访存慢&lt;/strong&gt;&amp;quot;。GPU 计算单元算力很猛，但显存带宽跟不上。Attention 计算大量时间花在&amp;quot;等数据从显存搬到计算单元&amp;quot;，这就是 &lt;strong&gt;memory-bound（访存受限）&lt;/strong&gt; 问题。&lt;/p&gt;
&lt;p&gt;三个痛点连成一条线：&lt;strong&gt;N² 复杂度让计算量平方膨胀；KV Cache 让长上下文显存爆掉；访存带宽让 GPU 算力发挥不出来。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="32-mqa极端共享的代价"&gt;3.2 MQA：极端共享的代价
&lt;/h3&gt;&lt;p&gt;MQA（Multi-Query Attention）的思路非常暴力：&lt;strong&gt;所有 head 共享同一份 K 和 V，只有 Q 是每个 head 独立的&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;直接后果是 KV Cache 立刻变成 1/H——原本 32 套 K/V 现在只存 1 套，显存压到 1/32。前面那个 17GB 的 KV Cache，用 MQA 后只剩 0.5GB。&lt;/p&gt;
&lt;p&gt;但代价是&lt;strong&gt;表达能力下降&lt;/strong&gt;。原本 32 个 head 各有 32 套不同的&amp;quot;视角&amp;quot;，可以从 32 个角度理解上下文；MQA 强行让 32 个 head 共用一套 K/V，多视角能力被压缩成单视角。实测大模型效果会下降 2-5%，对推理类任务有明显损失。&lt;/p&gt;
&lt;h3 id="33-gqa折中之道"&gt;3.3 GQA：折中之道
&lt;/h3&gt;&lt;p&gt;GQA（Grouped-Query Attention）是 MHA 和 MQA 的折中：&lt;strong&gt;把 H 个 head 分成 G 组，每组内部共享一份 K/V，组之间各自独立&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;数学上是一个连续光谱：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MHA：H 个 head，H 套 K/V&lt;/li&gt;
&lt;li&gt;MQA：H 个 head，1 套 K/V&lt;/li&gt;
&lt;li&gt;GQA：H 个 head，G 套 K/V（1 ≤ G ≤ H）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;G=H 退化成 MHA，G=1 退化成 MQA。Meta 的 GQA 论文里，G=8 配置下模型效果几乎和 MHA 持平（差距 &amp;lt; 0.5%），但 KV Cache 压到 1/4。这种&amp;quot;显存大幅下降、效果几乎不损失&amp;quot;的甜蜜点，让 GQA 成为现代大模型标配。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;谁在用 GQA：&lt;/strong&gt; Llama 2 70B、Llama 3 全系、Qwen 2/3 主力模型。DeepSeek V2/V3 用了另一条更激进的路线 MLA（Multi-head Latent Attention），把 K/V 压缩到低秩潜在空间存储，目标同样是压低 KV Cache。&lt;/p&gt;
&lt;h3 id="34-flash-attention从算法层面优化"&gt;3.4 Flash Attention：从算法层面优化
&lt;/h3&gt;&lt;p&gt;Flash Attention 完全是另一条赛道——&lt;strong&gt;不改 Attention 的数学公式，从底层实现优化&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;问题的根源在于 GPU 存储分两层：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HBM（高带宽显存）&lt;/strong&gt;：容量大（A100 是 80GB），带宽相对慢（1.5 TB/s）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SRAM（片上缓存）&lt;/strong&gt;：容量小（A100 每个 SM 只有 192KB），带宽极快（19 TB/s，是 HBM 的 13 倍）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;标准实现把 N×N 注意力矩阵在 HBM 上反复读写，访存时间远超计算时间。Flash Attention 提出&lt;strong&gt;分块 + 在线 softmax&lt;/strong&gt;：把 Q、K、V 切成小块（比如 128×128），每次只在 SRAM 里算一小块，算完直接累加到最终输出，不把 N×N 中间矩阵写回 HBM。&lt;/p&gt;
&lt;p&gt;在线 softmax 是关键数学技巧——softmax 本来要看&amp;quot;整行&amp;quot;才能算，Flash Attention 用分块计算同时维护&amp;quot;当前最大值 + 累积和&amp;quot;状态，每来一块做增量更新，最终结果和一次性算完全一样。&lt;/p&gt;
&lt;p&gt;效果：&lt;strong&gt;显存从 O(N²) 降到 O(N)，速度提升 2-4 倍，结果数学等价&lt;/strong&gt;。已迭代到 v3 版本，基本成为大模型推理框架的默认实现。&lt;/p&gt;
&lt;h3 id="35-四者的叠加关系"&gt;3.5 四者的叠加关系
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;优化方案&lt;/th&gt;
&lt;th&gt;改的是什么&lt;/th&gt;
&lt;th&gt;攻击的痛点&lt;/th&gt;
&lt;th&gt;效果损失&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MQA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Attention 结构（K/V 压成 1 份）&lt;/td&gt;
&lt;td&gt;显存大&lt;/td&gt;
&lt;td&gt;中等（2-5%）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GQA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Attention 结构（K/V 压成 G 份）&lt;/td&gt;
&lt;td&gt;显存大&lt;/td&gt;
&lt;td&gt;几乎无（&amp;lt; 0.5%）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Flash Attention&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Attention 实现（分块 + 在线 softmax）&lt;/td&gt;
&lt;td&gt;显存 + 访存 + 速度&lt;/td&gt;
&lt;td&gt;基本无（数学等价）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;最关键的认知：&lt;strong&gt;这三类优化是叠加关系，不是替代关系。&lt;/strong&gt; MQA/GQA 是&amp;quot;结构层&amp;quot;优化（改有几套 K/V），Flash Attention 是&amp;quot;实现层&amp;quot;优化（改计算执行方式）。它们攻击不同维度，可以同时使用。主流大模型的标配是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GQA 结构 + Flash Attention 实现
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;比如 Llama 3、Qwen 2、DeepSeek V3 都是这个组合。两者叠加后，7B 模型能在消费级显卡上跑 32K 长上下文。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点：&lt;/strong&gt; 面试官如果追问&amp;quot;只能选一个用，选哪个&amp;quot;，这是伪命题——真实工程里它们一定组合用，因为攻击的是不同维度的瓶颈。MLA（DeepSeek 用的低秩潜在注意力）可以作为加分项提一句。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第四章位置编码"&gt;第四章：位置编码
&lt;/h2&gt;&lt;h3 id="41-为什么需要位置编码"&gt;4.1 为什么需要位置编码
&lt;/h3&gt;&lt;p&gt;Self-Attention 有一个天然的缺陷：&lt;strong&gt;它的计算是对称的，不考虑词的顺序&lt;/strong&gt;。&amp;ldquo;我打你&amp;quot;和&amp;quot;你打我&amp;quot;对 Attention 来说可能得到一样的结果，因为它只看哪些词相关，不看谁在前谁在后。&lt;/p&gt;
&lt;p&gt;如果把输入换成&amp;quot;你打我&amp;rdquo;，三个 embedding 一模一样（只是位置变了），Attention 算出来的结果和&amp;quot;我打你&amp;quot;&lt;strong&gt;几乎完全相同&lt;/strong&gt;。但这两句话语义是反的。模型如果分不清位置，就分不清主语和宾语。&lt;/p&gt;
&lt;p&gt;那为什么不能直接用&amp;quot;1, 2, 3, 4&amp;quot;这种位置序号？因为序号是离散整数，加到连续 embedding 上会很别扭：第 1000 位的&amp;quot;1000&amp;quot;会把原本 -1 到 1 之间的 embedding 数值拉爆；而且整数序号对长序列没法泛化，训练见过 1-2048，推理来了 4096，这个数字模型从没见过。&lt;/p&gt;
&lt;p&gt;所以位置编码必须满足三个要求：&lt;strong&gt;数值范围合理&lt;/strong&gt;（不能覆盖 token embedding）、&lt;strong&gt;能区分不同位置&lt;/strong&gt;（每个位置有独特&amp;quot;指纹&amp;quot;）、&lt;strong&gt;能泛化到长序列&lt;/strong&gt;（最好支持外推）。&lt;/p&gt;
&lt;h3 id="42-sincos-绝对编码"&gt;4.2 sin/cos 绝对编码
&lt;/h3&gt;&lt;p&gt;2017 年原始 Transformer 用的就是 sin/cos 位置编码（Sinusoidal PE）。核心思路是用一组不同频率的 sin/cos 函数，给每个位置生成一个独特的&amp;quot;指纹向量&amp;quot;。&lt;/p&gt;
&lt;p&gt;模型 embedding 维度有 d 维，分成 d/2 对，每对用一组 sin/cos：第 1 对频率最快（高频），适合区分近距离位置；第 d/2 对频率最慢（低频），跨越很远位置才能区分开。类比几个不同频率的振子叠加，高频记&amp;quot;精细位置&amp;quot;，低频记&amp;quot;粗略位置&amp;quot;。&lt;/p&gt;
&lt;p&gt;使用方式是直接&lt;strong&gt;加到 token embedding 上&lt;/strong&gt;：最终输入 = token embedding + position embedding。加法不增加维度，神经网络可以从相加结果里自动解开两部分信息。&lt;/p&gt;
&lt;p&gt;优点是零参数、泛化性看起来不错。但致命问题是&lt;strong&gt;长上下文外推能力差&lt;/strong&gt;——训练时只学过&amp;quot;2K 以内的相对位置关系&amp;quot;，推理给 4K 输入，效果断崖下跌。&lt;/p&gt;
&lt;h3 id="43-rope-旋转位置编码"&gt;4.3 RoPE 旋转位置编码
&lt;/h3&gt;&lt;p&gt;RoPE（Rotary Position Embedding）是 2021 年中国学者苏剑林提出的，现已是大模型标配。核心思路一句话：&lt;strong&gt;不把位置信息加到 embedding 上，而是旋转 Q 和 K 向量&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;每个 token 的 Q/K 向量根据它的位置 m，被旋转一个对应角度 mθ（θ 是预设常数）。位置 0 不旋转，位置 1 旋转 θ，位置 2 旋转 2θ。类比钟表指针，位置越靠后指针转得越多。&lt;/p&gt;
&lt;p&gt;为什么旋转能表达位置？关键数学性质是：&lt;strong&gt;两个旋转后的向量做点积，结果只依赖于它们的&amp;quot;旋转角度差&amp;quot;&lt;/strong&gt;。位置 m 的 Q 和位置 n 的 K 做点积，结果只跟 (m-n) 这个相对距离有关，跟 m 和 n 各自的绝对值无关。这就把&amp;quot;相对位置&amp;quot;信息天然编进了 Attention 计算里。&lt;/p&gt;
&lt;p&gt;RoPE 的优点叠加起来才让它成为标配：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;天然的相对位置编码&lt;/strong&gt;，不用模型自己学相对关系&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;零参数&lt;/strong&gt;，纯数学旋转&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保留 token 向量长度&lt;/strong&gt;，旋转不改变模长只改变方向，不破坏 embedding 数值范围&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;和现代推理优化兼容&lt;/strong&gt;，只在 Q/K 上做旋转，跟 KV Cache、Flash Attention、GQA 无缝叠加&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;长上下文外推能力远好于 sin/cos&lt;/strong&gt;，配合 NTK Scaling、YaRN 等扩展技巧，可推到 32K、100K 甚至更长&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;谁在用 RoPE：&lt;/strong&gt; Llama 1/2/3 全系、Qwen 1/2/3 全系、DeepSeek 全系、Mistral/Mixtral 全系、GLM 系列。可以说 RoPE 已是大模型架构的事实标准。&lt;/p&gt;
&lt;h3 id="44-alibi-外推编码"&gt;4.4 ALiBi 外推编码
&lt;/h3&gt;&lt;p&gt;ALiBi（Attention with Linear Biases）是另一种相对位置编码方案，思路比 RoPE 更暴力：&lt;strong&gt;根本不动 Q、K、V，直接在注意力分数里加一个&amp;quot;距离惩罚项&amp;quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;softmax(QK^T)&lt;/code&gt; 之前，给每对 token 的注意力分数加上偏置 &lt;code&gt;-m × |i-j|&lt;/code&gt;，其中 |i-j| 是距离，m 是固定斜率（每个 head 不同）。直观理解：离得越远扣分越多，模型越倾向关注近邻。每个 head 用不同斜率，让不同 head 关注不同范围。&lt;/p&gt;
&lt;p&gt;优点是零参数、极简实现、天然支持长上下文外推（线性距离惩罚不存在训练截止）。缺点是表达力弱、过强的局部偏置，对需要长距离依赖的任务不利。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;谁用过 ALiBi：&lt;/strong&gt; MosaicML 的 MPT 系列、BLOOM 的某些版本。但都不是主流大模型。&lt;/p&gt;
&lt;h3 id="45-三者对比与选型"&gt;4.5 三者对比与选型
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;sin/cos&lt;/th&gt;
&lt;th&gt;ALiBi&lt;/th&gt;
&lt;th&gt;RoPE&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;编码类型&lt;/td&gt;
&lt;td&gt;绝对位置&lt;/td&gt;
&lt;td&gt;相对位置（距离惩罚）&lt;/td&gt;
&lt;td&gt;相对位置（旋转）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;注入方式&lt;/td&gt;
&lt;td&gt;加到 token embedding&lt;/td&gt;
&lt;td&gt;加到注意力分数&lt;/td&gt;
&lt;td&gt;旋转 Q/K 向量&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;长上下文外推&lt;/td&gt;
&lt;td&gt;较差（容易断崖）&lt;/td&gt;
&lt;td&gt;好（线性外推）&lt;/td&gt;
&lt;td&gt;很强（配合 NTK/YaRN）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;表达力&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;弱（过强局部偏置）&lt;/td&gt;
&lt;td&gt;强&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;主流采用&lt;/td&gt;
&lt;td&gt;原始 Transformer&lt;/td&gt;
&lt;td&gt;MPT、BLOOM&lt;/td&gt;
&lt;td&gt;Llama/Qwen/DeepSeek 全系&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;RoPE 赢在三个理由：&lt;strong&gt;长上下文外推能力&lt;/strong&gt;（配合 NTK/YaRN 生态，但上线前要看长上下文评测）；&lt;strong&gt;相对位置 + 表达力的平衡&lt;/strong&gt;（ALiBi 外推好但表达力不够，sin/cos 表达力够但外推差）；&lt;strong&gt;工程兼容性&lt;/strong&gt;（只在 Q/K 上做旋转，不改变其他计算，和所有推理优化无缝叠加）。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点：&lt;/strong&gt; 长上下文外推技巧（PI / NTK / YaRN）有些可以推理时直接改 RoPE 参数，但要做到稳定的 100K+ 长上下文，很多模型还会配合长上下文继续训练或校准。RoPE 地位稳固不是因为它能无成本无限外推，而是因为它给了社区一个很好调、很好扩展的基础。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第五章分词器tokenizer"&gt;第五章：分词器（Tokenizer）
&lt;/h2&gt;&lt;h3 id="51-为什么需要分词"&gt;5.1 为什么需要分词
&lt;/h3&gt;&lt;p&gt;大语言模型的本质是一个函数：输入一串整数（token ID 序列），输出下一个整数的概率分布。&lt;strong&gt;模型只能处理整数，不认识字符串。&lt;/strong&gt; Tokenizer 就是连接人类文字和模型整数世界的桥梁，做两件事：编码（文本 → token ID 序列）和解码（token ID 序列 → 文本）。&lt;/p&gt;
&lt;h3 id="52-bpe-算法原理"&gt;5.2 BPE 算法原理
&lt;/h3&gt;&lt;p&gt;最直接的两种分词方案都有致命缺陷：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;字符级分词&lt;/strong&gt;（每个字母/汉字一个 token）：词汇表小，但序列极长。一个&amp;quot;hello&amp;quot;变 5 个 token，Attention 的 O(N²) 计算量飙升，而且字符语义信息太少。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;词级分词&lt;/strong&gt;（每个完整单词一个 token）：词汇表膨胀到几十万，而且有严重的 OOV 问题——遇到训练时没见过的新词就无法处理，模型只能输出&amp;quot;未知词&amp;quot;标记，语义完全丢失。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;子词分词&lt;/strong&gt;就是这两者中间的甜蜜点。BPE（Byte Pair Encoding）是最常见的一类，原理分三步：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;初始化&lt;/strong&gt;：把训练语料拆成最小单元（单个字节或字符），形成初始词汇表&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;反复合并&lt;/strong&gt;：统计相邻 token pair 的出现频率，找到最高频的那对合并成新 token。比如&amp;quot;t&amp;quot;和&amp;quot;h&amp;quot;经常在一起，合并成&amp;quot;th&amp;quot;加入词汇表。继续找下一个，比如&amp;quot;th&amp;quot;和&amp;quot;e&amp;quot;合并成&amp;quot;the&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重复&lt;/strong&gt;直到词汇表达到预设大小（GPT-2 用了 50257，Llama 3 用了 128000）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;以&amp;quot;lowest&amp;quot;为例，BPE 可能分成&amp;quot;low&amp;quot;+&amp;ldquo;est&amp;rdquo;，因为都是高频子词。遇到新词&amp;quot;lowest123&amp;quot;，分成&amp;quot;low&amp;quot;+&amp;ldquo;est&amp;rdquo;+&amp;ldquo;1&amp;rdquo;+&amp;ldquo;2&amp;rdquo;+&amp;ldquo;3&amp;rdquo;，&lt;strong&gt;不会出现 OOV&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="53-子词分词的优势"&gt;5.3 子词分词的优势
&lt;/h3&gt;&lt;p&gt;子词分词的优势在于&amp;quot;动态范围&amp;quot;：高频词/字被合并成独立 token（效率高），低频词被拆成子词（能处理新词），介于字符级和词级之间。BPE 只是子词分词的一种，SentencePiece / Unigram、WordPiece 也很常见。&lt;/p&gt;
&lt;p&gt;中文没有空格分隔，BPE 面对中文的处理方式不同：常用汉字会直接作为独立 token（频率足够高），常见词语可能合并也可能拆分，取决于训练数据频率。实践估算经验规则：&lt;strong&gt;1000 个汉字大约对应 1000-1500 个 token&lt;/strong&gt;（汉字 token 化效率略低于英文）。但这只是粗估，Qwen、Llama、OpenAI 的 tokenizer 都不一样，正式算成本前一定要用目标模型的 tokenizer 跑一遍。&lt;/p&gt;
&lt;h3 id="54-分词对模型能力的影响"&gt;5.4 分词对模型能力的影响
&lt;/h3&gt;&lt;p&gt;理解 Tokenizer 对实际工程有几个直接影响：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;API 成本估算&lt;/strong&gt;：主流 LLM API 都按 token 计费，不是按字数。1000 汉字约 1000-1500 tokens，1000 英文单词约 1300 tokens，代码效率更低。预估费用必须用目标模型的 tokenizer 数出来。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;上下文窗口管理&lt;/strong&gt;：每个模型有最大 token 限制（Claude 200K、Qwen 128K），中文 + 代码混合内容很容易让你以为&amp;quot;才 5 万字应该不超&amp;quot;，实际算成 token 已经 8 万了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;避免截断重要信息&lt;/strong&gt;：文档卡在上下文边缘时，Tokenizer 可能把一个词从中间硬切开，导致下游解析或检索失败。工程上要保留几百 token 的安全 buffer。&lt;/p&gt;
&lt;p&gt;特殊 token（BOS、EOS、PAD、SEP，以及 ChatML 格式里的 &lt;code&gt;&amp;lt;|im_start|&amp;gt;&lt;/code&gt;）不是来自文本，而是给模型传递结构信息的，它们的 embedding 在训练中被专门优化。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点：&lt;/strong&gt; 面试被问到 Tokenizer，最重要的是先说清&amp;quot;模型只能处理整数&amp;quot;，Tokenizer 是文字到整数世界的桥梁。然后讲三种分词粒度的取舍（字符级太碎、词级太散、子词折中），再补实际工程影响（API 计费、上下文管理、避免截断）。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第六章大模型训练全景"&gt;第六章：大模型训练全景
&lt;/h2&gt;&lt;h3 id="61-预训练从海量文本中学习语言规律"&gt;6.1 预训练：从海量文本中学习语言规律
&lt;/h3&gt;&lt;p&gt;预训练是大模型能力的根基。做一个类比：培养一个能独当一面的员工，他得先有基础知识（从小学读到大学），再学会公司流程（SFT），最后懂职业素养（对齐）。大模型的三个训练阶段对应这三件事。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数据从哪来？&lt;/strong&gt; GPT-3 用了 3000 亿 token，Llama 3 用了 15 万亿 token。数据来源包括互联网网页（Common Crawl）、GitHub 代码、维基百科、扫描图书、论文、新闻。但原始数据充满垃圾，预训练前要做大量清洗——去重、过滤低质量、识别语言、剔除有害信息。&lt;strong&gt;一个高质量训练集的清洗成本可能比模型训练本身还贵&lt;/strong&gt;，这是大模型公司的核心竞争力之一。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;训练目标&lt;/strong&gt;：CLM（预测下一个 token）。要预测&amp;quot;北京是中国的____&amp;quot;，模型必须知道&amp;quot;北京是首都&amp;quot;；要预测&amp;quot;如果 x=2，那么 x²=____&amp;quot;，模型必须会算数。所有能力都被这个目标&lt;strong&gt;逼着学会了&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;计算开销&lt;/strong&gt;：训练 GPT-3 据估算花了约 3.14×10²³ 次浮点运算。用一张 A100 需 36 万年。OpenAI 用几百到几千张 GPU 并行训练几个月，算力成本上千万美元。&lt;/p&gt;
&lt;p&gt;预训练完后，模型有了一个&amp;quot;大脑&amp;quot;，但它&lt;strong&gt;不会回答问题，只会续写&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="62-sft从续写器到对话助手"&gt;6.2 SFT：从&amp;quot;续写器&amp;quot;到&amp;quot;对话助手&amp;quot;
&lt;/h3&gt;&lt;p&gt;预训练后的模型本质是&amp;quot;文本续写机器&amp;quot;。你问它&amp;quot;天空为什么是蓝色的？&amp;quot;，它可能续写成&amp;quot;天空为什么是蓝色的？这是个有趣的科学问题。今天天气不错……&amp;ldquo;一直发散下去，根本没在回答你。&lt;/p&gt;
&lt;p&gt;SFT 的目的就是把这个&amp;quot;续写机器&amp;quot;改造成&amp;quot;对话机器&amp;rdquo;。训练数据格式从&amp;quot;连续文本&amp;quot;变成&amp;quot;(指令，期望回答)&amp;ldquo;对：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;指令：请用简单易懂的语言解释为什么天空是蓝色的
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;回答：天空呈现蓝色是因为大气中的散射现象……
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;模型慢慢学会&amp;quot;看到这种格式就该给完整答案，不要无限续写&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数据质量比数量更重要。&lt;/strong&gt; Llama 2 用了约 100 万条 SFT 数据，每条精心标注。AlpacaFarm 的研究发现：&lt;strong&gt;几千条高质量数据训出来的效果，比几十万条低质量数据要好&lt;/strong&gt;。数据多样性也很关键，要覆盖问答、写作、代码、数学、翻译等各种场景。&lt;/p&gt;
&lt;h3 id="63-对齐rlhfdpo让模型符合人类偏好"&gt;6.3 对齐（RLHF/DPO）：让模型符合人类偏好
&lt;/h3&gt;&lt;p&gt;SFT 后模型会按指令回答了，但回答风格不一定讨喜——可能太啰嗦、太简洁、偶尔说不该说的话。对齐（Alignment）就是补这一课。&lt;/p&gt;
&lt;p&gt;经典方法是 &lt;strong&gt;RLHF&lt;/strong&gt;（基于人类反馈的强化学习）：先让人类标注员对同一问题的多个回答排序 → 训一个独立的&amp;quot;奖励模型&amp;quot;学会自动打分 → 用 PPO 算法调整大模型参数让它生成高分回答。同时维护一个&amp;quot;参考模型&amp;quot;用 KL 散度约束，防止主模型&amp;quot;钻空子&amp;quot;（reward hacking）。&lt;/p&gt;
&lt;p&gt;后来斯坦福提出 &lt;strong&gt;DPO&lt;/strong&gt;（直接偏好优化），把 RLHF 的优化目标用数学等价方式改写成纯监督学习，&lt;strong&gt;不需要奖励模型，也不需要 PPO&lt;/strong&gt;。直接拿(问题，好回答，差回答)三元组训练。训练简单、稳定、容易实现，开源社区大量采用。（对齐技术的详细对比见第八章。）&lt;/p&gt;
&lt;h3 id="64-三个阶段为什么缺一不可"&gt;6.4 三个阶段为什么缺一不可
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;只做预训练不做 SFT：模型只会续写，根本不会对话&lt;/li&gt;
&lt;li&gt;只做预训练 + SFT 不做对齐：模型会对话了，但可能生成有害内容、自信地胡说&lt;/li&gt;
&lt;li&gt;只做 SFT + 对齐跳过预训练：在&amp;quot;空壳&amp;quot;上优化，没有底层知识&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;预训练决定能力天花板，SFT 给格式，对齐给价值观。&lt;/strong&gt; 所有主流大模型训练的基本框架都是这三段。&lt;/p&gt;
&lt;h3 id="65-scaling-law-与涌现能力"&gt;6.5 Scaling Law 与涌现能力
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Scaling Law&lt;/strong&gt; 讲的是大模型的损失值如何随&lt;strong&gt;模型规模 N、训练数据量 D、训练算力 C&lt;/strong&gt; 这三个量变化的可预测关系：&lt;/p&gt;
&lt;p&gt;$$\text{loss}(N) \approx \left(\frac{N_c}{N}\right)^{\alpha_N}$$&lt;/p&gt;
&lt;p&gt;它震撼业界有三个原因：&lt;strong&gt;可预测&lt;/strong&gt;（能提前算投入产出比）、&lt;strong&gt;没有看到饱和点&lt;/strong&gt;（继续加大还能提升）、&lt;strong&gt;三个变量可独立做幂律分析&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;涌现能力&lt;/strong&gt;是 Scaling Law 的特殊副产物：某项能力在小模型上几乎看不到，规模超过临界点（典型 50B-100B）突然表现出来——多步推理、上下文学习、跨语言迁移。但要注意 2023 年斯坦福 &lt;em&gt;Mirage&lt;/em&gt; 论文的挑战：很多&amp;quot;涌现&amp;quot;可能只是评估指标不连续造成的测量假象。&lt;/p&gt;
&lt;h3 id="66-chinchilla-比例与-llama-3-的数据突破"&gt;6.6 Chinchilla 比例与 Llama 3 的数据突破
&lt;/h3&gt;&lt;p&gt;2022 年 DeepMind 的 Chinchilla 论文做了个壕实验：&lt;strong&gt;训了 400 个不同规模的模型&lt;/strong&gt;，发现给定固定训练算力 C，参数和数据要按接近 &lt;strong&gt;1:20&lt;/strong&gt; 的比例配（每个参数配 20 tokens）。&lt;/p&gt;
&lt;p&gt;验证实验震撼业界：70B 的 Chinchilla 配 1.4T tokens，&lt;strong&gt;明显超过&lt;/strong&gt; 4 倍参数的 280B Gopher 和 175B 的 GPT-3。GPT-3 的比例是 1:1.7，&lt;strong&gt;严重欠训&lt;/strong&gt;，数据缺口 12 倍。&lt;/p&gt;
&lt;p&gt;但 2024 年 Llama 3 做了件激进的事：&lt;strong&gt;把数据量推到 1:1875 的极端配比&lt;/strong&gt;（8B 参数 / 15T tokens，是 Chinchilla 推荐的 94 倍），loss 一直稳定下降，训出来的 8B 模型&lt;strong&gt;多项基准超过 GPT-3 175B&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这说明 Chinchilla 的 1:20 不是&amp;quot;数据上限&amp;quot;，而是&amp;quot;&lt;strong&gt;给定训练算力时怎么分配更划算&lt;/strong&gt;&amp;ldquo;的经验答案。如果愿意投入更多训练计算，继续喂更多高质量 token，loss 仍可能下降。Qwen3-0.6B 用 36T tokens 训一个 0.6B 小模型（比例 1:60000），把这个趋势推到更极端。&lt;/p&gt;
&lt;p&gt;为什么会出现这个趋势？两个工程原因：&lt;strong&gt;推理成本&lt;/strong&gt;（8B 部署一台消费级 GPU，175B 要好几台 H100）和&lt;strong&gt;数据相对便宜&lt;/strong&gt;（数据清洗花钱但比 GPU 集群便宜得多）。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点：&lt;/strong&gt; 选型时问的不是&amp;quot;谁最大&amp;rdquo;，而是&amp;quot;这个模型训练充分吗？数据质量怎么样？它为训练算力最优还是推理成本最优设计？&amp;quot;。涌现能力对选型的影响：依赖多步推理/ICL 的任务最低门槛 30B-70B，简单分类/抽取/摘要 7B-13B 完全够用。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第七章微调技术"&gt;第七章：微调技术
&lt;/h2&gt;&lt;h3 id="71-全量微调-vs-参数高效微调"&gt;7.1 全量微调 vs 参数高效微调
&lt;/h3&gt;&lt;p&gt;首先回答一个前置问题：&lt;strong&gt;什么时候才真的需要微调？&lt;/strong&gt; 很多人一遇到&amp;quot;模型表现不好&amp;quot;就想上微调，但工业界踩过坑的人都知道，&lt;strong&gt;微调是最后手段，不是第一选择&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;能用 Prompt + Few-shot 解决就别上微调；能用 System Prompt 控制风格就别上微调；能用 RAG 接知识库就别上微调。微调的成本远比想象大：需要高质量数据集（标注几万到几十万）、GPU 资源、工程经验，最坑的是维护成本——基础模型一升级，之前微调的版本基本就废了。&lt;/p&gt;
&lt;p&gt;只有这些都不行时才考虑微调。特别提醒：如果需求是&amp;quot;补充经常变化的事实知识&amp;quot;（产品价格、政策条款、库存状态），微调不是好选择，应该用 RAG 实时查。&lt;/p&gt;
&lt;p&gt;理解了&amp;quot;该不该微调&amp;quot;，再看&amp;quot;微调有哪些方案&amp;quot;。这里有个特别容易踩的坑：很多人把&amp;quot;全量微调、LoRA、QLoRA、SFT、DPO&amp;quot;都当成同一类&amp;quot;不同微调方法&amp;quot;，其实它们分两个&lt;strong&gt;正交维度&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;维度一：改哪些参数&lt;/strong&gt;（全量微调 / LoRA / QLoRA）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;维度二：学什么目标&lt;/strong&gt;（SFT / DPO）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这两个维度可以任意组合：可以用 LoRA 做 SFT，也可以用 LoRA 做 DPO。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;全量微调&lt;/strong&gt;：所有参数都改。效果上限最高，但代价大——7B 模型 FP16 训练要存权重(14GB) + 梯度(14GB) + 优化器状态(56GB) = 80GB+。更糟的是&lt;strong&gt;灾难性遗忘&lt;/strong&gt;：所有参数被改写，新任务学好了，预训练的通用能力反而下降。&lt;/p&gt;
&lt;h3 id="72-lora-的五大优点与原理"&gt;7.2 LoRA 的五大优点与原理
&lt;/h3&gt;&lt;p&gt;LoRA（Low-Rank Adaptation）的核心洞见：模型参数的&amp;quot;更新量&amp;quot;（ΔW = W微调后 - W原始）虽然维度很大，但真正有意义的变化只发生在一个&lt;strong&gt;低维子空间&lt;/strong&gt;里。权重的更新具有&amp;quot;&lt;strong&gt;内在低秩性&lt;/strong&gt;&amp;quot;，秩通常只有 8-16。&lt;/p&gt;
&lt;p&gt;基于此，LoRA 冻结原始权重 W 不动，在旁边新增两个小矩阵 A（d×r）和 B（r×d），训练时只更新 A 和 B：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# W 是原始权重（冻结），A 和 B 是两个小矩阵（可训练）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# α 是缩放因子（超参，控制 LoRA 更新强度）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;W&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;α&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;类比&amp;quot;给书批注&amp;quot;：全量微调是把书重印一遍改掉原文，LoRA 是在空白处贴便利贴，原文一字不动。&lt;/p&gt;
&lt;p&gt;参数量对比：4096×4096 权重原本 1677 万参数，LoRA r=16 只需 13.1 万参数，减少约 128 倍。整个 7B 模型可训练参数从 70 亿降到 2000 万左右。&lt;/p&gt;
&lt;p&gt;LoRA 除了&amp;quot;省参数&amp;quot;，还有五个被低估的优点：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;优点一：推理零开销。&lt;/strong&gt; 训练完把 &lt;code&gt;α * B·A&lt;/code&gt; 合并到 W 上得到 &lt;code&gt;W_merged&lt;/code&gt;，推理时和原始模型完全一样，没有额外计算。这一点比 Adapter 强——Adapter 推理时每层都要过额外小网络。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;W_merged&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;W&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;α&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 提前算好，只做一次&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="n"&gt;W_merged&lt;/span&gt; &lt;span class="c1"&gt;# 推理时和原始模型完全一样&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;优点二：模块化插拔。&lt;/strong&gt; 一个基础模型 + 多套 LoRA 权重，按需加载。7B 基础模型 14GB，每套 LoRA 才几十 MB，可以同时维护客服、代码、翻译几套 LoRA 热切换。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;peft&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PeftModel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;base_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoModelForCausalLM&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Qwen2.5-7B&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 场景一：客服请求，挂载客服 LoRA&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;lora_cs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PeftModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;path/to/customer_service_lora&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 场景二：代码问题，换成代码 LoRA，基础模型不用重新加载&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;lora_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PeftModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;path/to/coding_lora&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;优点三：灾难性遗忘风险更低。&lt;/strong&gt; 原始权重全程冻结，所有学习都在旁路小矩阵里，相当于在原知识旁边贴便利贴，通用能力更容易保住。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;优点四：训练更稳定。&lt;/strong&gt; 可训练参数少 100 倍以上，梯度搜索空间大幅缩小，对学习率等超参不敏感，调参成本低。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;优点五（进阶）：权重可加权混合。&lt;/strong&gt; 多个 LoRA 可以加权混合实现能力融合，不用重新训练：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;W&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; = W + α₁ * (B₁ · A₁) + α₂ * (B₂ · A₂)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;调整 α₁ 和 α₂ 的比例就能调整两种能力的&amp;quot;配比&amp;quot;。这叫 &lt;strong&gt;LoRA Merging&lt;/strong&gt;，是 Model Merging 领域的重要方向。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;全量微调&lt;/th&gt;
&lt;th&gt;Adapter&lt;/th&gt;
&lt;th&gt;LoRA&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;可训练参数量&lt;/td&gt;
&lt;td&gt;全部（100%）&lt;/td&gt;
&lt;td&gt;少量额外参数（~1%）&lt;/td&gt;
&lt;td&gt;少量旁路参数（~0.1%-1%）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;推理额外开销&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;有（每层额外网络）&lt;/td&gt;
&lt;td&gt;无（可合并进 W）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;灾难性遗忘风险&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;部署灵活性&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;高（一基底 + 多套 LoRA）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;权重可组合性&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;td&gt;不支持&lt;/td&gt;
&lt;td&gt;支持（LoRA Merging）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="73-qlora"&gt;7.3 QLoRA
&lt;/h3&gt;&lt;p&gt;QLoRA 把微调门槛进一步往下打：先把基础模型用 4-bit 量化（NF4 格式），把 7B 模型显存从 14GB 压到 4GB，然后套 LoRA。整个微调显存降到 10GB 以内，&lt;strong&gt;一张 4090（24GB）就能微调 7B 甚至 13B 模型&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;QLoRA 的精度损失非常小，实测和全精度 LoRA 几乎没差别。这一招直接让微调民主化了，Alpaca、Vicuna 这些早期开源指令模型基本都是用 QLoRA 训出来的。&lt;/p&gt;
&lt;h3 id="74-post-training-的五种家族"&gt;7.4 Post-Training 的五种家族
&lt;/h3&gt;&lt;p&gt;SFT 之后还有一整族 Post-Training 方法，详见第八章。这里只需记住：微调的两个维度（改哪些参数 × 学什么目标）可以任意组合，最常见的工业组合是 &lt;strong&gt;QLoRA + SFT&lt;/strong&gt;（个人开发者，性价比最高）和 &lt;strong&gt;LoRA + SFT + DPO&lt;/strong&gt;（社区主流）。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点：&lt;/strong&gt; 绝大多数项目能用 QLoRA + SFT 搞定，没必要上更重的方案。这种&amp;quot;克制&amp;quot;的工程态度，比&amp;quot;为了微调而微调&amp;quot;的新人思维成熟得多。能用轻量方案搞定的需求，一定不要上重的——训练成本、调参难度、维护成本都会指数级上升。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第八章对齐技术"&gt;第八章：对齐技术
&lt;/h2&gt;&lt;h3 id="81-rlhfppo的完整流程"&gt;8.1 RLHF（PPO）的完整流程
&lt;/h3&gt;&lt;p&gt;RLHF 是 OpenAI 在 InstructGPT 中开创的方案，也是 ChatGPT 早期版本的核心训练方法。整个流程分三步：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一步：收集偏好数据。&lt;/strong&gt; 人类标注员对同一 Prompt 的多个回答排序（A 比 B 好、B 比 C 好）。排序比绝对评分更稳定，因为人类比较两个回答的相对好坏比给绝对分数容易。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二步：训练奖励模型（Reward Model）。&lt;/strong&gt; 用偏好数据训一个独立的小模型，输入(Prompt + 回答)，输出一个分数。训练目标是让&amp;quot;人类觉得好的回答&amp;quot;分数高。这个奖励模型代替了人类，可以批量自动打分。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三步：用 PPO 优化主模型。&lt;/strong&gt; 主模型生成回答 → 奖励模型打分 → PPO 调整主模型参数往高分方向走。同时维护&amp;quot;参考模型&amp;quot;（SFT 模型冻结副本），用 KL 散度约束主模型不要离参考模型太远，防止 reward hacking。&lt;/p&gt;
&lt;p&gt;整个 PPO 训练同时需要维护 &lt;strong&gt;4 个模型&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# PPO 训练时需要同时维护的四个模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;policy_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_sft_model&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 主模型（正在被优化的）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;reference_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_sft_model&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 参考模型（冻结，SFT 副本，用于 KL 约束）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;reward_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_reward_model&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 奖励模型（裁判，给回答打分）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;value_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_value_model&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 价值模型（RL 辅助，估算未来奖励期望）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;4 个模型同时加载到显存，每个都和主模型差不多大，显存占用是 SFT 的好几倍。加上 RL 本身的不稳定性（超参敏感、容易 reward hacking、训练曲线震荡），能驾驭 PPO 的团队凤毛麟角。&lt;/p&gt;
&lt;h3 id="82-dpo去掉奖励模型的两步法"&gt;8.2 DPO：去掉奖励模型的两步法
&lt;/h3&gt;&lt;p&gt;DPO 是 2023 年斯坦福提出的方案，核心是一个数学上的&lt;strong&gt;等价转换&lt;/strong&gt;：RLHF 的优化目标可以推导改写成纯监督学习目标函数，&lt;strong&gt;不需要显式训练奖励模型&lt;/strong&gt;。直觉上，&amp;ldquo;奖励模型&amp;quot;的功能可以被&amp;quot;主模型相对于参考模型的概率比值&amp;quot;完全替代。&lt;/p&gt;
&lt;p&gt;数据格式简单到不能再简单：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;prompt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;如何学好 Python？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;chosen&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;建议先从官方文档入手，配合做小项目实践……&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;rejected&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Python 很简单，随便找个教程看看就行了……&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;DPO 损失函数直觉：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# DPO 损失（简化直觉版）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sigma&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;beta&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chosen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chosen&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# 主模型 vs 参考模型在&amp;#34;好回答&amp;#34;上的概率比&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rejected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rejected&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# 主模型 vs 参考模型在&amp;#34;差回答&amp;#34;上的概率比&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 目标：让 chosen 的比值 &amp;gt; rejected 的比值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;只需 &lt;strong&gt;2 个模型&lt;/strong&gt;（policy + reference），训练稳定，实现简单。代价是效果上限略低于精心调过的 PPO（没法像 RL 那样探索数据之外的好回答），且依赖偏好数据质量。&lt;/p&gt;
&lt;h3 id="83-ppo-vs-dpo-的核心区别4-模型-vs-2-模型"&gt;8.3 PPO vs DPO 的核心区别（4 模型 vs 2 模型）
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;PPO&lt;/th&gt;
&lt;th&gt;DPO&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;是否需要奖励模型&lt;/td&gt;
&lt;td&gt;需要（单独训练）&lt;/td&gt;
&lt;td&gt;不需要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;同时维护的模型数&lt;/td&gt;
&lt;td&gt;4 个&lt;/td&gt;
&lt;td&gt;2 个&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;训练稳定性&lt;/td&gt;
&lt;td&gt;较差（RL 不稳定）&lt;/td&gt;
&lt;td&gt;好（等价监督学习）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;实现难度&lt;/td&gt;
&lt;td&gt;高（需要 RL 基础设施）&lt;/td&gt;
&lt;td&gt;低（标准训练框架即可）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;表达能力&lt;/td&gt;
&lt;td&gt;强（可探索数据之外）&lt;/td&gt;
&lt;td&gt;稍弱（受偏好数据分布限制）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一句话总结：&lt;strong&gt;PPO 是&amp;quot;先训裁判再训选手&amp;rdquo;，DPO 是&amp;quot;直接拿比赛录像告诉选手哪个动作对哪个动作错&amp;quot;。&lt;/strong&gt; 两者目标一致，但 DPO 省掉了&amp;quot;奖励模型&amp;quot;这个中间层。&lt;/p&gt;
&lt;h3 id="84-grpo-等新方法"&gt;8.4 GRPO 等新方法
&lt;/h3&gt;&lt;p&gt;GRPO（Group Relative Policy Optimization）是 DeepSeek 2024 年在 DeepSeekMath 论文里提出的 PPO 改进版，因 DeepSeek R1 火遍整个圈子。&lt;/p&gt;
&lt;p&gt;要理解 GRPO，得先搞清 PPO 为什么需要 Value Model。PPO 的优势函数（Advantage）= 实际奖励 - 预期奖励，Value Model 的作用就是估计&amp;quot;预期奖励&amp;quot;作为基线。但 Value Model 是独立神经网络，规模和主模型一样大，要单独训练占显存。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GRPO 的核心创新：直接砍掉 Value Model，用&amp;quot;组内相对排名&amp;quot;估计优势。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;具体流程：对一个问题 q，从主模型采样 G 个回答（典型 G=8），用奖励模型（或对错判定）打分得到 r₁&amp;hellip;r_G，计算组内相对优势：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;A_i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r_i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r_1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;r_G&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r_1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;r_G&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&amp;ldquo;组内平均分&amp;quot;充当了 Value Model 的角色，这个基线天然就有，不用单独训练。4 模型架构变成 3 模型（Policy / Reference / Reward），显存接近 DPO 但保留 RL 探索能力。&lt;/p&gt;
&lt;p&gt;GRPO 还有个杀手级特性：&lt;strong&gt;对&amp;quot;可验证任务&amp;quot;特别友好&lt;/strong&gt;。数学题、代码题这类&amp;quot;答案对就是对、错就是错&amp;quot;的场景，r_i 直接用 0/1 判定就行，连 Reward Model 都省了。DeepSeek R1-Zero 就是这么做的，纯靠强化学习训出推理能力。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;谁在用 GRPO：&lt;/strong&gt; DeepSeek R1 / R1-Zero、DeepSeek-Math、Qwen-Math 系列。&lt;/p&gt;
&lt;p&gt;除了 GRPO，还有两类重要的 Post-Training 方法：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;拒绝采样（Rejection Sampling）&lt;/strong&gt;：根本不用 RL。让模型对每个 Prompt 生成多个回答 → 用奖励模型筛出高分的 → 当作新 SFT 数据再做一轮 SFT。就是&amp;quot;生成 → 筛选 → 再 SFT&amp;quot;循环。Llama 2 的对齐流程用了这个。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RLAIF&lt;/strong&gt;：用更强的 AI 模型代替人类标注偏好。Anthropic 的 Constitutional AI 用 Claude 自己批评自己的回答生成偏好对。优点是批量生成、成本低，缺点是依赖强教师 AI。&lt;/p&gt;
&lt;p&gt;最关键的认知：&lt;strong&gt;这五类方法是组合用的，不是替代。&lt;/strong&gt; Llama 2-Chat 用的是&amp;quot;SFT + 拒绝采样 + PPO/RLHF&amp;rdquo;；DeepSeek R1 用的是&amp;quot;SFT 冷启动 + 多轮 GRPO + 拒绝采样&amp;quot;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点：&lt;/strong&gt; 选型逻辑——资源有限 + 实现优先简单选 DPO；推理类任务（数学、代码）+ 想用 RL 探索上限选 GRPO；想要稳定基线再精修先做拒绝采样；数据规模大 + 标注成本敏感用 RLAIF；大厂资源充足追求最高上限跑完整 RLHF 或 GRPO。注意别说&amp;quot;Llama 2 是 DPO 路线&amp;quot;，它公开流程是 SFT + 拒绝采样 + PPO/RLHF。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第九章推理优化"&gt;第九章：推理优化
&lt;/h2&gt;&lt;h3 id="91-解码策略greedybeam-search采样"&gt;9.1 解码策略（Greedy/Beam Search/采样）
&lt;/h3&gt;&lt;p&gt;每生成一个 token，模型输出一个 vocabulary 大小的概率分布，解码策略就是&amp;quot;怎么从这个分布里挑下一个 token&amp;quot;。不同策略对应&amp;quot;生成任务到底有没有最优答案&amp;quot;的不同假设。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;贪心解码&lt;/strong&gt;：每步选概率最高的 token。简单、可复现，但有&amp;quot;复读机问题&amp;quot;——一旦走进自我加强的循环就出不来，会一直重复。适合代码生成、SQL、JSON 抽取等有标准答案的精确任务。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Beam Search&lt;/strong&gt;：每步保留 Top-B 条候选路径，最后选总概率最高的整条序列。在翻译时代是王者（翻译有&amp;quot;单一最优译文&amp;quot;），但 LLM 时代几乎被弃用——开放式生成没有&amp;quot;最优答案&amp;quot;，Beam Search 优化&amp;quot;整体概率最高&amp;quot;反而输出最 boring 的回答，还和 KV Cache、Flash Attention 等推理优化不兼容。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;采样族&lt;/strong&gt;：用随机性换多样性。普通采样有长尾噪声问题，发展出三种调节器：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Temperature&lt;/strong&gt;：缩放概率分布锐度。T=0 等价贪心，T&amp;lt;1 更确定，T&amp;gt;1 更发散&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Top-K&lt;/strong&gt;：固定截断，只从概率最高 K 个 token 里采样&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Top-P（Nucleus）&lt;/strong&gt;：自适应截断，按累积概率到 P 为止。比 Top-K 智能——确定性问题候选池小，开放问题候选池大&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;选型口诀：&lt;strong&gt;任务有标准答案 → 贪心或 T=0；任务有多种合理答案要稳 → Top-P=0.9 + T=0.7；任务鼓励多样性 → Top-P=0.95 + T=1.0+。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="92-temperaturetop-ptop-k-参数调节"&gt;9.2 Temperature/Top-p/Top-k 参数调节
&lt;/h3&gt;&lt;p&gt;这三个参数的作用维度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Temperature&lt;/strong&gt; 控制&amp;quot;分布的松紧&amp;quot;（缩放尖锐度）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Top-K&lt;/strong&gt; 是&amp;quot;固定截断&amp;quot;（只保留前 K 个词）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Top-P&lt;/strong&gt; 是&amp;quot;自适应截断&amp;quot;（按累积概率截断到 P）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;最关键的实战经验：一次主要调一个参数。&lt;/strong&gt; 最常见做法是先调 Temperature，Top-P 保持默认或 0.9~1.0，Top-K 不设置。不要同时大幅调 temperature 和 top_p，两者会互相干扰。&lt;/p&gt;
&lt;p&gt;常见踩坑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同时调 temperature 高 + top_p 低（让分布变平坦再截掉一半，互相打架）&lt;/li&gt;
&lt;li&gt;同时设置 top_k 和 top_p（两个都在做截断，候选池变得奇怪）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;参考配置：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 代码生成 / 精确问答（要可重复、不能出错）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 日常对话 / 总结摘要（要连贯自然但不能太发散）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 创意写作 / 头脑风暴（要多样性，允许偶尔出奇）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt; &lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.95&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="93-kv-cache-原理与-prompt-caching"&gt;9.3 KV Cache 原理与 Prompt Caching
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;KV Cache 是&amp;quot;单次推理内&amp;quot;的优化。&lt;/strong&gt; 自回归生成的朴素实现是 O(N³)——每步都重算前面所有 token 的 attention。但第 2 步算的&amp;quot;P&amp;quot;的 attention 和第 1 步完全一样，纯浪费。&lt;/p&gt;
&lt;p&gt;KV Cache 把前面所有 token 的 K 和 V 缓存在显存里，每次新 token 只算自己的 Q、K、V，然后跟缓存的 K/V 做 attention。总计算量从 O(N³) 降到 O(N²)。这不是&amp;quot;锦上添花&amp;quot;，是&amp;quot;让自回归生成可行的基本盘&amp;quot;。&lt;/p&gt;
&lt;p&gt;但 KV Cache 显存代价不小（7B 模型 32K 上下文要 17GB），所以有一系列围绕它的优化（PagedAttention、KV Cache 量化、MQA/GQA 共享 K/V）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prompt Caching 是&amp;quot;跨请求&amp;quot;的优化。&lt;/strong&gt; 把 KV Cache 的复用范围从&amp;quot;单次推理内&amp;quot;扩展到&amp;quot;不同请求之间&amp;quot;。如果两个请求的 Prompt 前缀完全相同（比如都用同样的 System Prompt），第一个请求算完的 KV Cache 保留下来，第二个请求直接复用，只算新增部分。&lt;/p&gt;
&lt;p&gt;两者关系：&lt;strong&gt;同一个底层机制在两个时间尺度上的应用。&lt;/strong&gt; KV Cache 是单次推理内 token 之间共享，Prompt Caching 是不同请求之间共享。&lt;/p&gt;
&lt;p&gt;主流 API 实现分两派：Claude 用显式标记（&lt;code&gt;cache_control&lt;/code&gt; 断点），OpenAI 用自动缓存（前缀超过 1024 tokens 自动缓存）。Claude 命中缓存的 token 费用是正常的 10%，写入有 1.25x 费用，后续 2 次以上命中就省钱。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最常见的工程陷阱：固定内容在前、动态内容在后。&lt;/strong&gt; 前缀必须完全一致才能命中，哪怕多一个空格、改一个字符就 miss。把日期、用户名这类动态内容放在固定内容前面，会让缓存永远失效。Claude 的 ephemeral 缓存默认 5 分钟有效期，低流量应用可能省不到。&lt;/p&gt;
&lt;h3 id="94-量化技术awqgptqnf4"&gt;9.4 量化技术（AWQ/GPTQ/NF4）
&lt;/h3&gt;&lt;p&gt;量化（Quantization）的本质是把模型参数从高精度浮点（FP16）映射到低精度整数（INT8/INT4）。7B 模型 FP16 占 14GB，INT4 只剩 3.5GB，推理还能加速 2-4 倍。&lt;/p&gt;
&lt;p&gt;精度边界：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;量化位数&lt;/th&gt;
&lt;th&gt;模型体积&lt;/th&gt;
&lt;th&gt;平均精度损失&lt;/th&gt;
&lt;th&gt;实用性&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FP16&lt;/td&gt;
&lt;td&gt;14 GB（7B）&lt;/td&gt;
&lt;td&gt;基线&lt;/td&gt;
&lt;td&gt;训练用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INT8&lt;/td&gt;
&lt;td&gt;7 GB&lt;/td&gt;
&lt;td&gt;&amp;lt; 0.5%&lt;/td&gt;
&lt;td&gt;几乎无损&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INT4&lt;/td&gt;
&lt;td&gt;3.5 GB&lt;/td&gt;
&lt;td&gt;1-3%&lt;/td&gt;
&lt;td&gt;主流部署&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INT3&lt;/td&gt;
&lt;td&gt;2.6 GB&lt;/td&gt;
&lt;td&gt;5-10%&lt;/td&gt;
&lt;td&gt;边缘设备&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;但&amp;quot;平均损失 1-3%&amp;ldquo;背后藏着一个魔鬼：&lt;strong&gt;精度损失不是均匀分布的&lt;/strong&gt;。简单分类几乎无损，数学推理可能损失 5-10%，长链路代码生成可能损失 10%+。&lt;/p&gt;
&lt;p&gt;三种主流算法各有核心创新：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GPTQ&lt;/strong&gt;：基于&amp;quot;误差补偿&amp;quot;的逐层量化。每量化一层，用校准数据测出量化误差，把误差补偿到下一层。数学严谨，支持 INT3 极端低位，但量化耗时长。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AWQ&lt;/strong&gt;：基于&amp;quot;激活感知&amp;quot;的权重保护。核心洞见是&lt;strong&gt;模型里约 1% 的权重承担了 99% 的输出贡献&lt;/strong&gt;（Salient Weights）。通过逐通道缩放把重要权重保护好，其他激进压缩。推理速度快、效果稳。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;QLoRA 的 NF4&lt;/strong&gt;：NormalFloat 4-bit，专为权重的近高斯分布设计的非均匀量化。让 16 个量化值的分布也成正态分布形状，0 附近刻度密、远离 0 刻度少。配合双重量化和分页优化器，让 4090 能微调 7B 模型。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键认知：量化算法（GPTQ/AWQ）和文件格式（GGUF）是两层东西。&lt;/strong&gt; GPTQ/AWQ 是&amp;quot;怎么把高精度变低精度&amp;quot;的算法，GGUF 是 llama.cpp 用的&amp;quot;怎么存低精度权重&amp;quot;的文件格式容器。两者经常被混淆。&lt;/p&gt;
&lt;p&gt;选型：生产部署看重速度优先 AWQ / GPTQ / FP8；追求精度选 FP16 / INT8；个人微选取 QLoRA NF4；边缘设备选 GGUF Q4_K_M。&lt;strong&gt;部署量化模型前必须在自己的业务场景下做评测&lt;/strong&gt;，不能直接看论文平均数。&lt;/p&gt;
&lt;h3 id="95-moe-混合专家架构"&gt;9.5 MoE 混合专家架构
&lt;/h3&gt;&lt;p&gt;MoE（Mixture of Experts）的核心思想是把 Transformer 中的 FFN 复制成 N 份&amp;quot;专家&amp;rdquo;，加一个 Router 决定每个 token 进哪个专家。&lt;/p&gt;
&lt;p&gt;核心设计哲学是&amp;quot;&lt;strong&gt;总参数大，但激活参数小&lt;/strong&gt;&amp;quot;。比如 DeepSeek V3 总参数 671B，但每个 token 推理时只激活 37B（约 1/18）。能用&amp;quot;总参数 671B 的知识量&amp;quot;+&amp;ldquo;激活参数 37B 的推理成本&amp;rdquo;，达到 Dense 模型做不到的&amp;quot;学得多 + 跑得快&amp;quot;。&lt;/p&gt;
&lt;p&gt;三个核心组件：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 多个专家&lt;/strong&gt;：FFN 复制 N 份，各自学到不同&amp;quot;擅长方向&amp;quot;（数学、代码、中文等）。专家分化不是预先指定的，是训练中自然涌现的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Router&lt;/strong&gt;：一个简单线性层算分 + Top-K 选取：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;gate_logits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;token_embedding&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="n"&gt;W_router&lt;/span&gt; &lt;span class="c1"&gt;# 算每个专家的偏好分数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;expert_weights&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;softmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gate_logits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 归一化成概率&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;top_k_experts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;topk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expert_weights&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 选 Top-K 个专家&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;3. 负载均衡损失&lt;/strong&gt;：防止&amp;quot;专家不平衡&amp;quot;——Router 偏爱某几个专家，其他专家根本没被训过。把专家使用率的方差作为惩罚加进总损失。DeepSeek V3 还提出了 Auxiliary-Loss-Free 策略（动态调整专家偏置项，不引入额外损失）。&lt;/p&gt;
&lt;p&gt;主流 MoE 对比：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DeepSeek V3&lt;/strong&gt;：256 routed experts + 1 shared，Top-8 激活，671B/37B，激活率 5.5%&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mixtral 8x7B&lt;/strong&gt;：8 experts，Top-2 激活，47B/13B，激活率 28%&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Qwen MoE 30B-A3B&lt;/strong&gt;：30B/3B，激活率 10%&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;趋势是&amp;quot;专家越来越多、激活率越来越低&amp;quot;，更细粒度的稀疏化带来更好的算力性价比。&lt;/p&gt;
&lt;p&gt;关键的反直觉点：&lt;strong&gt;显存按总参数走（671B 全量加载），但推理速度按激活参数走（接近 37B Dense）&lt;/strong&gt;。这就是 MoE&amp;quot;学得多 + 跑得快&amp;quot;的来源。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点：&lt;/strong&gt; 推理优化是多层叠加的体系：KV Cache 是基本盘，GQA + Flash Attention 压显存和加速，量化压模型体积，MoE 解耦知识量和推理成本，Prompt Caching 省跨请求成本。选型时看的是&amp;quot;攻击哪个维度的瓶颈&amp;quot;，不是单点替换。部署 MoE 模型比 Dense 复杂得多（需要专家并行、All-to-All 通信），建议先测试环境跑通再上生产。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第十章prompt-工程与思维链"&gt;第十章：Prompt 工程与思维链
&lt;/h2&gt;&lt;h3 id="101-prompt-的五要素"&gt;10.1 Prompt 的五要素
&lt;/h3&gt;&lt;p&gt;同一个模型、同一个任务，一个好 Prompt 和一个差 Prompt 输出的质量差距可以有一个数量级。新手写 Prompt 最常见的问题不是&amp;quot;太短&amp;quot;，而是&amp;quot;&lt;strong&gt;模糊&lt;/strong&gt;&amp;quot;——没说清楚角色、任务、上下文、格式、示例。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Role（角色设定）&lt;/strong&gt;：告诉模型&amp;quot;你是谁&amp;quot;。角色越具体，模型&amp;quot;人设&amp;quot;越稳定。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;❌ 你是一个助手，帮我分析这段代码。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;✅ 你是一位有 10 年经验的 Python 后端工程师，专注代码 Review 和性能优化，
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 熟悉常见的安全漏洞。回答时直接指出问题，解释原因，给出具体的修改方案。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Task（任务描述）&lt;/strong&gt;：用清晰动词把任务边界说明白，复杂任务拆成子步骤。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;❌ 帮我写一篇文章。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;✅ 写一篇面向高中生的 800 字科普文章，主题是「为什么黑洞会弯曲时空」。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 用日常生活类比帮助读者理解，避免数学公式，结尾给一个思考题。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Context（背景信息）&lt;/strong&gt;：把业务场景塞给模型。模型不了解你的行业、用户是谁。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Format（输出格式）&lt;/strong&gt;：最容易被忽略但对程序解析影响最大的要素。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;❌ 分析这条用户评论的情感。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;✅ 以 JSON 格式输出，包含：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - &amp;#34;summary&amp;#34;：20 字以内的评论概述
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - &amp;#34;sentiment&amp;#34;：正面 / 中性 / 负面 三选一
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - &amp;#34;keywords&amp;#34;：最多 3 个关键词的列表
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Examples（示例）&lt;/strong&gt;：Few-shot 学习，比纯文字描述效果好得多。与其花很多时间描述想要的风格，不如直接给 1-3 个输入/输出例子。&lt;/p&gt;
&lt;p&gt;一个完整的好 Prompt 把五要素都补全：角色（技术内容编辑）、任务（摘要提炼）、背景（后端工程师受众）、格式（三段式固定结构）、长度约束。交给不同模型、不同时间执行，输出格式和质量都会高度稳定。&lt;/p&gt;
&lt;h3 id="102-cot-的草稿纸原理"&gt;10.2 CoT 的&amp;quot;草稿纸&amp;quot;原理
&lt;/h3&gt;&lt;p&gt;CoT（Chain-of-Thought）的本质是让模型&amp;quot;推出来&amp;quot;而不是&amp;quot;直接猜出来&amp;quot;。&lt;/p&gt;
&lt;p&gt;为什么有效？模型是一个 token 一个 token 生成的，每生成一个新 token 时都能&amp;quot;看到&amp;quot;前面所有已生成的内容。让它先生成推理步骤，等于给了它一张&amp;quot;&lt;strong&gt;草稿纸&lt;/strong&gt;&amp;quot;——复杂的中间状态不再需要全部存在模型的隐状态里，通过显式输出记下来，减轻了推理负担。后面生成答案时能利用前面的推理上下文，自然出错就少了。&lt;/p&gt;
&lt;p&gt;两种 CoT 形式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Few-shot CoT&lt;/strong&gt;：Prompt 里给几个完整的&amp;quot;推理示例&amp;quot;，效果最稳定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zero-shot CoT&lt;/strong&gt;：问题末尾加一句&amp;quot;请分步思考后再给结论&amp;quot;，简单但效果略差&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Self-Consistency 是 CoT 的升级版：对同一问题用较高 Temperature 采样 N 条独立推理路径，取最终答案出现最多次的那个（多数投票）。直觉是&amp;quot;正确答案可通过多种路径得到，错误答案相对分散&amp;quot;。在数学推理任务上经常能提升 5-15 个百分点，代价是 N 倍 API 调用成本。&lt;/p&gt;
&lt;h3 id="103-cot-的局限性"&gt;10.3 CoT 的局限性
&lt;/h3&gt;&lt;p&gt;CoT 不是万能的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;token 消耗大&lt;/strong&gt;：推理链额外几百上千 token，成本和延迟都上去&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;对简单问题适得其反&lt;/strong&gt;：让模型对&amp;quot;1+1 等于几&amp;quot;也展开推理是浪费&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;推理链本身会出错&lt;/strong&gt;：第 2 步错了，第 3、4 步基于错误前提继续推导，错误累积传导&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;对纯记忆类任务没帮助&lt;/strong&gt;：&amp;ldquo;2020 年奥运会在哪&amp;quot;不需要推理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2026 年的工程实践里，不建议默认把完整推理链原样展示给最终用户——一方面多花 token，另一方面完整思考链里可能有不稳定或不该暴露的内容。更稳的做法是让模型内部先分析，最终只输出简洁依据或关键步骤。&lt;/p&gt;
&lt;h3 id="104-幻觉的三层根因与缓解策略"&gt;10.4 幻觉的三层根因与缓解策略
&lt;/h3&gt;&lt;p&gt;学术界对 LLM 幻觉的定义：&lt;strong&gt;模型生成了与训练事实、用户输入、或已知世界不一致的内容，但语言上看起来很流畅合理。&lt;/strong&gt; 关键两个特征：内容错 + 听起来对。&lt;/p&gt;
&lt;p&gt;根因有三层：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根因一：训练数据本身有错。&lt;/strong&gt; 互联网语料充满错误、矛盾、过时信息，模型全都学进参数，没有&amp;quot;真假区分&amp;quot;机制。但这只是冰山一角——即使数据 100% 正确，模型还是会幻觉。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根因二：生成机制是&amp;quot;续写&amp;quot;不是&amp;quot;查询&amp;rdquo;。&lt;/strong&gt; 这是最深的根因。LLM 本质是 next-token prediction，不是查询知识库。模型对&amp;quot;自己知不知道某件事&amp;quot;没有显式信号。碰到不熟悉的问题，会按训练时见过的相似上下文&amp;quot;编一个看起来合理的答案&amp;quot;。&lt;/p&gt;
&lt;p&gt;这就是为什么 &lt;strong&gt;Temperature=0 也会幻觉&lt;/strong&gt;——贪心解码选概率最高的 token，但&amp;quot;概率最高&amp;quot;不等于&amp;quot;正确&amp;quot;。如果模型对某事实记忆模糊，概率分布可能是&amp;quot;茅 35% / 周 32%&amp;quot;，T=0 铁定选&amp;quot;茅&amp;quot;，错得很自信。温度只能减少&amp;quot;同一错误重复出现的随机性&amp;quot;，不能修正&amp;quot;错误本身&amp;quot;。&lt;/p&gt;
&lt;p&gt;LLM 的事实记忆是&lt;strong&gt;参数化知识&lt;/strong&gt;（分布式编码在 1700 亿参数里）——模糊的、不可检索的、不可验证的。而 RAG 的&lt;strong&gt;检索式知识&lt;/strong&gt;每个事实有明确出处，找到了就找到了，找不到就明确返回空。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根因三：对齐目标的副作用。&lt;/strong&gt; SFT 和 RLHF 训练时，&amp;ldquo;自信地回答&amp;quot;几乎永远比&amp;quot;我不知道&amp;quot;得分高——人类标注员打分依据更多是&amp;quot;读起来像不像专家&amp;rdquo;，不一定知道答案对不对。奖励模型学到&amp;quot;自信 = 高分，谨慎 = 低分&amp;quot;，PPO 把这个偏好放大，模型变成&amp;quot;永远自信、永远不拒答&amp;quot;。&lt;/p&gt;
&lt;p&gt;三类幻觉：&lt;strong&gt;事实性幻觉&lt;/strong&gt;（编造不存在的事实）、&lt;strong&gt;推理性幻觉&lt;/strong&gt;（推理链条错乱）、&lt;strong&gt;上下文不一致&lt;/strong&gt;（违背用户给的明确条件）。&lt;/p&gt;
&lt;p&gt;缓解方案分三层组合用：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;训练层&lt;/strong&gt;：SFT 数据加大量&amp;quot;拒答样例&amp;quot;、校准（Calibration）训练让&amp;quot;自信度&amp;quot;和&amp;quot;正确率&amp;quot;对齐、用奖励模型筛掉幻觉回答。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推理层&lt;/strong&gt;：CoT 暴露推理错误、Temperature 调低减少随机偏差、Self-Consistency 多次采样投票、约束解码限制只能输出合法 vocabulary。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;系统层&lt;/strong&gt;：RAG 让模型&amp;quot;看着资料答&amp;quot;、后处理事实核查、强制带引用来源。&lt;/p&gt;
&lt;p&gt;最关键的认知：&lt;strong&gt;幻觉不可能完全消除&lt;/strong&gt;，因为它是 LLM 概率生成机制的固有副产物。工程目标是&amp;quot;降低发生率 + 让用户能识别&amp;quot;，不是&amp;quot;彻底消灭&amp;quot;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点：&lt;/strong&gt; Prompt 工程不是&amp;quot;把人话写清楚&amp;quot;，是有方法论的工程问题——五要素、Few-shot、CoT 触发、迭代闭环。要建测试集（30-50 条覆盖正常和边缘情况），每次改动都跑一遍看通过率，遵循&amp;quot;每次只改一处&amp;quot;原则。幻觉缓解要训练、推理、系统三层一起上，少哪层都不行。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="第十一章部署与评测"&gt;第十一章：部署与评测
&lt;/h2&gt;&lt;h3 id="111-主流部署框架对比vllmsglangtgi"&gt;11.1 主流部署框架对比（vLLM/SGLang/TGI）
&lt;/h3&gt;&lt;p&gt;部署框架解决的核心问题：&lt;strong&gt;怎么在固定硬件上跑得更快、更省显存、支持更多并发？&lt;/strong&gt; 直接用 transformers 库有三大痛点：KV Cache 显存碎片严重、批量调度低效、重复计算。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;vLLM&lt;/strong&gt;（UC Berkeley）：核心创新是 &lt;strong&gt;PagedAttention&lt;/strong&gt;，灵感来自操作系统虚拟内存。把 KV Cache 切成固定大小 Block（16 个 token 一块），每个请求拿到逻辑 Block 列表，由 Block Table 映射到物理显存。显存利用率从 30-40% 拉到 90%+。配合 &lt;strong&gt;Continuous Batching&lt;/strong&gt;（请求异步加入退出，每个 token 步骤动态组 batch），吞吐率比 static batching 高 3-5 倍。是当前生产 API 的事实标准。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SGLang&lt;/strong&gt;（LMSYS）：核心创新是 &lt;strong&gt;RadixAttention&lt;/strong&gt;，把多请求的共享前缀组织成 Radix Tree（基数树）。多个请求如果开头 N 个 tokens 一样，就共享根节点到第 N 层的同一条路径。KV Cache 显存按&amp;quot;所有请求的并集&amp;quot;算，而不是&amp;quot;各自的总和&amp;quot;。在 Agent / 多轮对话 / Few-shot 场景（前缀重复率高）下比 vLLM 省 50-80% 显存、首 token 延迟降 2-3 倍。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TGI&lt;/strong&gt;（HuggingFace）：核心卖点是生态集成 + 企业级特性。直接读 HF Hub 模型 ID 自动下载，支持鉴权、Prometheus metrics、健康检查。适合已有 HF 流程的团队，但极致吞吐通常不如 vLLM / SGLang。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;llama.cpp&lt;/strong&gt;：CPU / 边缘设备的事实标准。纯 C++ 重写整个推理栈，配合 GGUF 量化文件格式，让 7B 模型在 MacBook Pro、树莓派、手机上跑。M3 Max（128GB 统一内存）能跑 70B 模型。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TensorRT-LLM&lt;/strong&gt;（NVIDIA）：针对 NVIDIA GPU 做极致优化，性能通常比 vLLM 再高 10-30%，但部署复杂（每个模型/GPU 组合要编译 engine），只支持 NVIDIA GPU。&lt;/p&gt;
&lt;p&gt;选型决策矩阵：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;推荐&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;生产高吞吐 LLM API&lt;/td&gt;
&lt;td&gt;vLLM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent / 多轮对话 / Few-shot&lt;/td&gt;
&lt;td&gt;SGLang&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;拥抱 HF 生态、企业级&lt;/td&gt;
&lt;td&gt;TGI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;本地 / Mac / 边缘 / 无 GPU&lt;/td&gt;
&lt;td&gt;llama.cpp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;极致性能、自家定制&lt;/td&gt;
&lt;td&gt;TensorRT-LLM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;vLLM 和 SGLang 是&amp;quot;&lt;strong&gt;互补不替代&lt;/strong&gt;&amp;ldquo;的关系——业内已有公司混用（高吞吐路由用 vLLM，Agent 路由用 SGLang）。&lt;/p&gt;
&lt;h3 id="112-评测体系的三个层次"&gt;11.2 评测体系的三个层次
&lt;/h3&gt;&lt;p&gt;学术 Benchmark 适合横向对比，但&lt;strong&gt;不能完全相信&lt;/strong&gt;，因为存在严重的&amp;rdquo;&lt;strong&gt;数据污染&lt;/strong&gt;&amp;ldquo;问题——模型在预训练时可能已经见过测试题。&lt;/p&gt;
&lt;p&gt;主流学术 Benchmark：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MMLU / MMLU-Pro&lt;/strong&gt;：57 学科综合知识&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HumanEval / MBPP / SWE-bench Verified&lt;/strong&gt;：代码能力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GSM8K / MATH / GPQA&lt;/strong&gt;：数学和科学推理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MT-Bench / Arena / τ-bench&lt;/strong&gt;：对话、偏好、工具调用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HELM / LiveBench / Humanity&amp;rsquo;s Last Exam&lt;/strong&gt;：综合或更新型评测&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;面对 Benchmark 局限，最务实的做法是建&lt;strong&gt;业务测试集&lt;/strong&gt;：从真实用户请求采样 50-200 条，人工标注期望答案，每次改 Prompt 或换模型都跑一遍。评分方式：客观任务用程序自动验证，主观任务用 LLM-as-Judge（让强模型代评分，人工抽查 10-20% 校准）。&lt;/p&gt;
&lt;p&gt;完整的评测体系是**&amp;ldquo;学术 Benchmark + 业务测试集 + 线上指标&amp;quot;的闭环**：离线评估帮你找问题、快速迭代；线上指标（满意度、任务完成率、会话放弃率）告诉你优化是否真正改善了用户体验。&lt;/p&gt;
&lt;h3 id="113-模型选型四维度"&gt;11.3 模型选型四维度
&lt;/h3&gt;&lt;p&gt;模型选型从来不是看跑分最高，是看&amp;rdquo;&lt;strong&gt;合规、成本、延迟、能力特征&lt;/strong&gt;&amp;ldquo;四个维度匹配业务需求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;合规&lt;/strong&gt;：国内 ToB 项目里，数据出境合规是死线。再强的海外模型，数据分类分级、客户合同、监管要求过不了就只能做离线评测。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;成本&lt;/strong&gt;：Agent 内部循环调用如果硬上最贵的标杆模型，可能一个月把预算烧穿。高频节点要用性价比高的模型。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;延迟&lt;/strong&gt;：对延迟敏感的在线服务，推理速度和首 token 延迟是硬指标。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;能力特征&lt;/strong&gt;：不同模型各有特长——DeepSeek 推理和性价比突出、Qwen 中文和工具调用稳定、豆包工程生态和并发能力强。&lt;/p&gt;
&lt;p&gt;实战中不死磕单一模型，而是设计&lt;strong&gt;Model Routing（模型路由）&lt;/strong&gt;：格式要求严格的调度节点用结构化输出稳定的模型，高频推理用性价比高的模型，特别难的问题路由给更强但更贵的模型，敏感数据走合规可控的链路。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;实践要点：&lt;/strong&gt; 部署选型看的是&amp;quot;攻击哪个痛点&amp;rdquo;——vLLM 攻显存碎片和吞吐，SGLang 攻共享前缀，TGI 攻生态集成，llama.cpp 攻 CPU/边缘。评测不能只看学术 Benchmark（数据污染），必须建自己的业务测试集 + 线上指标闭环。模型选型四维度（合规、成本、延迟、能力），国内企业项目合规是死线。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="结尾"&gt;结尾
&lt;/h2&gt;&lt;h3 id="核心知识点回顾"&gt;核心知识点回顾
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LLM 的本质&lt;/strong&gt;是&amp;quot;用海量语料预训练、参数到百亿千亿规模、自回归生成文本的统一模型&amp;rdquo;。三个本质区别：任务统一（Prompt 接口）、生成式（输出文本）、涌现（学到没教过的能力）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transformer 的核心&lt;/strong&gt;是 Self-Attention：Q/K/V 从同一输入通过三个独立矩阵投影得到，除以 √d_k 防止 softmax 变 one-hot 导致梯度消失。Decoder-only 胜在&amp;quot;预测下一个 token&amp;quot;目标极其统一 + 可在海量无标注文本上自监督 + 规模越大涌现越强。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;注意力优化是叠加不是替代&lt;/strong&gt;：MQA/GQA 是&amp;quot;结构层&amp;quot;优化（改 K/V 套数），Flash Attention 是&amp;quot;实现层&amp;quot;优化（分块 + 在线 softmax）。主流标配是 GQA + Flash Attention。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RoPE 赢在三个维度的均衡&lt;/strong&gt;：相对位置编码 + 长上下文外推（配合 NTK/YaRN）+ 工程兼容性（和 KV Cache/Flash Attention/GQA 无缝叠加）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;BPE 子词分词&lt;/strong&gt;是字符级和词级的甜蜜点：控制词汇表大小 + 处理新词不 OOV + 保留语义信息。1000 汉字约 1000-1500 tokens，正式算成本必须用目标模型 tokenizer。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;训练三阶段缺一不可&lt;/strong&gt;：预训练定天花板（预测下一个 token，烧钱最多）、SFT 给格式（几千条高质量 &amp;gt; 几十万条粗糙）、对齐给价值观（RLHF/DPO）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Chinchilla 1:20 不是数据上限&lt;/strong&gt;，是&amp;quot;给定训练算力时怎么分配更划算&amp;quot;。Llama 3 用 1:1875 配比训出 8B 超越 GPT-3 175B，说明&amp;quot;小参数 + 海量数据&amp;quot;在推理成本最优方向上大有可为。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LoRA 五大优点&lt;/strong&gt;：推理零开销（可合并进 W）、模块化插拔（一基底多 LoRA）、灾难性遗忘风险低、训练稳定、权重可组合。它是 PEFT 事实标准不是因为单一优势，是五者叠加。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;对齐五大家族组合使用&lt;/strong&gt;：RLHF（4 模型，效果上限高）、DPO（2 模型，绕过奖励模型）、GRPO（砍 Value Model 用组内归一化，对可验证任务友好）、拒绝采样（迭代 SFT 不用 RL）、RLAIF（强 AI 当老师）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;幻觉不可能完全消除&lt;/strong&gt;，因为 LLM 本质是&amp;quot;按概率续写&amp;quot;不是&amp;quot;查询数据库&amp;quot;。Temperature=0 也会幻觉——概率最高的 token 不等于正确的 token。缓解要训练、推理、系统三层一起上。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="与其他主题的关联"&gt;与其他主题的关联
&lt;/h3&gt;&lt;p&gt;本文是&amp;quot;AI 知识体系&amp;quot;系列的开篇，后续主题与本篇的关联如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RAG（检索增强生成）&lt;/strong&gt;：是幻觉缓解的系统层方案，把&amp;quot;模糊的参数化记忆&amp;quot;换成&amp;quot;精确的检索结果&amp;quot;。理解 KV Cache 和 Prompt Caching 是理解 RAG 性能优化的前提。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent / 多智能体&lt;/strong&gt;：依赖 Tool Use、多轮对话、长上下文，这正是 SGLang RadixAttention 的优势场景。Model Routing 是 Agent 系统的成本控制核心。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;微调实战&lt;/strong&gt;：本文讲了 LoRA/QLoRA 的原理，实战篇会讲数据构造、训练参数调优、回归评测的具体流程。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;推理服务架构&lt;/strong&gt;：本文讲了 vLLM/SGLang 的核心创新，架构篇会讲多副本部署、负载均衡、显存调度、监控告警的完整方案。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="推荐进一步阅读"&gt;推荐进一步阅读
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;论文&lt;/strong&gt;：《Attention is All You Need》（Transformer）、Chinchilla（缩放定律）、《Are Emergent Abilities a Mirage?》（涌现争议）、RoPE 原文（苏剑林）、LoRA 原文、DPO 原文、Flash Attention 原文、DeepSeek V3 / R1 技术报告&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;官方文档&lt;/strong&gt;：vLLM（PagedAttention）、SGLang（RadixAttention）、HuggingFace PEFT（LoRA/QLoRA 实践）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实践资源&lt;/strong&gt;：Llama 3 / Qwen / DeepSeek 的模型卡和技术报告，了解真实工业级模型的训练配比和架构选择&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文基于 22 篇大模型工程主题素材整理而成，覆盖从 LLM 本质、Transformer 架构、注意力优化、位置编码、分词器、训练全景、微调、对齐、推理优化、Prompt 工程到部署评测的完整知识链路。如有错误欢迎指正。&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;</description></item><item><title>AI大模型工程知识体系总览与导论</title><link>https://blog.irudder.me/ai/ai-systematization/00-Introduction-to-AI-Large-Model-Engineering-Knowledge-System.html</link><pubDate>Thu, 23 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/ai-systematization/00-Introduction-to-AI-Large-Model-Engineering-Knowledge-System.html</guid><description>&lt;h1 id="ai大模型工程知识体系总览与导论"&gt;AI大模型工程知识体系总览与导论
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;本文是「AI知识成长体系」系列的开篇，为全系列8篇文章提供路线图与认知框架。无论你是刚接触大模型的初学者，还是已有工程经验的开发者，都可以从这篇文章找到适合自己的学习路径。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一为什么需要这套知识体系"&gt;一、为什么需要这套知识体系
&lt;/h2&gt;&lt;p&gt;2026年，AI Agent开发的浪潮已经席卷整个互联网行业。不仅是AI算法、AI应用工程师这些「天生AI」的岗位，连后端开发、前端开发、数据开发这些原本跟AI隔了一道墙的岗位，面试官也开始问起AI题了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;「你的项目里有没有用过LLM？怎么用的？」&lt;/li&gt;
&lt;li&gt;「假如让你做一个Agent，你会怎么设计？」&lt;/li&gt;
&lt;li&gt;「RAG工作流程是怎样的？」&lt;/li&gt;
&lt;li&gt;「MCP和Skills有什么区别？」&lt;/li&gt;
&lt;li&gt;「Claude Code的源码架构你了解吗？」&lt;/li&gt;
&lt;li&gt;「Harness Engineering是什么？Agent怎么越用越聪明？」&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些问题已经悄悄出现在各种岗位的面试里。AI时代，每个工程师都得懂点大模型，不然很容易掉队。&lt;/p&gt;
&lt;p&gt;但问题在于，大模型领域的知识碎片化严重。网上有无数的教程、博客、视频，但大多数只覆盖某个点——要么只讲Prompt工程，要么只讲RAG，要么只讲Agent——缺乏一条从底层原理到工程实践、从概念到落地的完整知识链路。&lt;/p&gt;
&lt;p&gt;这套系列文章的目标，就是把大模型工程领域的核心知识，按照一条清晰的认知主线串联起来，形成一套&lt;strong&gt;既有深度、又能让初学者入门、还能让有经验者增进&lt;/strong&gt;的完整知识成长体系。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="二知识体系的六大支柱"&gt;二、知识体系的六大支柱
&lt;/h2&gt;&lt;p&gt;经过对大模型工程领域系统性的梳理（覆盖7大板块、97篇深度文章），我们将整个知识体系划分为六大核心主题，它们之间存在明确的依赖关系和演进逻辑：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ AI大模型工程知识体系 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 支柱一：大模型工程基础（LLM Fundamentals） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Transformer架构与注意力机制 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 训练三阶段（预训练→SFT→对齐） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 推理优化（KV Cache、量化、解码策略） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Prompt工程与CoT │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── 部署与评测 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 支柱二：RAG检索增强生成（Retrieval-Augmented Generation） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 文档切割与Embedding │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 向量数据库与索引 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 检索优化（Query改写、多路召回、Rerank） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 高级范式（Self-RAG、CRAG、GraphRAG/LightRAG） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── 生产落地（评估、动态更新、幻觉规避） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 支柱三：LLM工具调用（Tool Use / Function Calling） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Function Calling原理与训练 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── MCP协议（标准化工具封装与发现） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Skill（任务流程知识化） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── A2A协议（Agent间协作） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── 通信协议与LLM网关 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 支柱四：LangChain框架（LLM应用开发框架） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 核心组件（Model I/O、Chains、Memory、Agents） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── LCEL表达式语言 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── LangGraph多Agent编排 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── LangSmith调试与监控 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── 框架选型与工程实践 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 支柱五：Agent智能体（Autonomous AI Agent） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 核心架构（感知→规划→行动→反思） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 设计范式（ReAct、Plan-and-Execute、Reflection） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 记忆机制与任务拆分 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Harness Engineering &amp;amp; Loop Engineering │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 多Agent协作与通信 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── OpenClaw与手搓Agent │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ▼ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 支柱六：Claude Code实战（AI Coding Engineering） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 基础使用与CLAUDE.md项目记忆 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Skill机制与SDD规约驱动开发 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 源码架构（Query Loop/Compact/grep/Memory/SubAgent） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── 系统提示词工程（Fable 5泄漏分析） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── AI编程方法论（grill-me/expertise over coding） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="为什么是这个顺序"&gt;为什么是这个顺序？
&lt;/h3&gt;&lt;p&gt;这六大支柱不是随意排列的，而是一条&lt;strong&gt;从底层到上层、从原理到应用、从概念到落地&lt;/strong&gt;的认知演进路线：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;大模型工程基础&lt;/strong&gt;是地基。不懂Transformer、不懂训练流程、不懂推理优化，后面的一切都是空中楼阁。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAG&lt;/strong&gt;是大模型最成熟的应用模式。它解决了大模型「知识被冻结」的核心问题，是绝大多数企业AI落地的第一步。GraphRAG和LightRAG进一步引入图结构，解决复杂关系推理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具调用&lt;/strong&gt;是大模型从「说话」变成「做事」的关键。没有工具调用，大模型只是一个聊天机器人；有了工具调用，它才可能成为真正的Agent。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LangChain框架&lt;/strong&gt;是工程化的加速器。当你理解了原理，框架帮你把各种组件标准化组合，快速构建应用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent&lt;/strong&gt;是终极形态。Agent = LLM + RAG + 工具调用 + 记忆 + 规划 + 反思，它是前面所有知识的集大成者。Harness Engineering和Loop Engineering代表了Agent工程的最新演进。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Code实战&lt;/strong&gt;是AI工程的前沿阵地。通过拆解Claude Code的源码架构和系统提示词，你能看到一个工业级AI Coding Agent是如何设计的——这是Agent理论在真实产品中的最佳实践。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="三系列文章目录与阅读指南"&gt;三、系列文章目录与阅读指南
&lt;/h2&gt;&lt;p&gt;本系列共8篇文章，建议按顺序阅读，但也可以根据自身情况跳读：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;序号&lt;/th&gt;
&lt;th&gt;标题&lt;/th&gt;
&lt;th&gt;定位&lt;/th&gt;
&lt;th&gt;适合读者&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;00&lt;/td&gt;
&lt;td&gt;本文：AI大模型工程知识体系总览与导论&lt;/td&gt;
&lt;td&gt;路线图&lt;/td&gt;
&lt;td&gt;所有人&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;01&lt;/td&gt;
&lt;td&gt;大模型基础与工程化实践&lt;/td&gt;
&lt;td&gt;底层原理&lt;/td&gt;
&lt;td&gt;需要理解LLM本质的开发者&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;02&lt;/td&gt;
&lt;td&gt;RAG检索增强生成——从原理到工程落地&lt;/td&gt;
&lt;td&gt;核心应用&lt;/td&gt;
&lt;td&gt;需要构建知识库应用的开发者&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;03&lt;/td&gt;
&lt;td&gt;LLM工具调用深度解析——从Function Calling到MCP&lt;/td&gt;
&lt;td&gt;能力扩展&lt;/td&gt;
&lt;td&gt;需要让LLM调用外部工具的开发者&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;04&lt;/td&gt;
&lt;td&gt;LangChain框架全解析——架构、组件与实战&lt;/td&gt;
&lt;td&gt;工程框架&lt;/td&gt;
&lt;td&gt;需要快速构建LLM应用的开发者&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;05&lt;/td&gt;
&lt;td&gt;Agent智能体——从概念到自主推理与行动&lt;/td&gt;
&lt;td&gt;终极形态&lt;/td&gt;
&lt;td&gt;需要构建自主AI系统的开发者&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;06&lt;/td&gt;
&lt;td&gt;Claude Code实战——AI编程工程深度拆解&lt;/td&gt;
&lt;td&gt;前沿实践&lt;/td&gt;
&lt;td&gt;需要用AI编程或理解Agent产品的开发者&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;07&lt;/td&gt;
&lt;td&gt;AI知识成长体系总纲——学习路径与进阶指南&lt;/td&gt;
&lt;td&gt;成长指南&lt;/td&gt;
&lt;td&gt;所有想要系统提升的读者&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="不同读者的推荐阅读路径"&gt;不同读者的推荐阅读路径
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;初学者路径（0基础入门）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00（导论）→ 01（大模型基础，重点看概念部分）→ 02（RAG，重点看流程）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 07（学习路径指南）→ 按需深入03/04/05/06
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;后端/前端工程师路径（想快速应用）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00（导论）→ 01（快速浏览原理）→ 02（RAG实战）→ 04（LangChain框架）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 06（Claude Code，AI编程提效）→ 05（Agent概念）→ 03（工具调用，按需）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;AI应用工程师路径（系统深入）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00 → 01 → 02 → 03 → 04 → 05 → 06 → 07（全部完整阅读）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;面试冲刺路径（高频考点）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00 → 01（Transformer/训练/推理优化）→ 02（RAG全流程）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 03（MCP vs FC vs Skill）→ 05（Agent范式/多Agent/Harness Engineering）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 06（Claude Code源码/系统提示词）→ 07（查漏补缺）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;AI编程方向路径（想用好AI Coding工具）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;00 → 06（Claude Code完整阅读）→ 05（Agent理论支撑）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;→ 03（Skill/MCP理解）→ 01（模型理解，按需）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="四核心认知框架理解大模型工程的三个层次"&gt;四、核心认知框架：理解大模型工程的三个层次
&lt;/h2&gt;&lt;p&gt;在深入各个主题之前，先建立一个贯穿全系列的核心认知框架。大模型工程可以理解为三个层次：&lt;/p&gt;
&lt;h3 id="第一层模型层model大脑"&gt;第一层：模型层（Model）——「大脑」
&lt;/h3&gt;&lt;p&gt;这是最底层的物理基础，关注的是&lt;strong&gt;模型本身是怎么构成的、怎么训练出来的、怎么推理的&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;核心问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Transformer架构为什么有效？Self-Attention的数学原理是什么？&lt;/li&gt;
&lt;li&gt;大模型是怎么从海量文本中「学」到知识的？预训练、SFT、对齐三个阶段分别做什么？&lt;/li&gt;
&lt;li&gt;推理时怎么加速？KV Cache、量化、MoE各解决什么问题？&lt;/li&gt;
&lt;li&gt;为什么大模型会「幻觉」？能消除吗？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一层对应系列第01篇。&lt;/p&gt;
&lt;h3 id="第二层能力层capability技能"&gt;第二层：能力层（Capability）——「技能」
&lt;/h3&gt;&lt;p&gt;模型本身只是一个「会接续文本的大脑」，要让它在真实场景中有用，需要给它叠加两层能力：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;知识能力（RAG）：&lt;/strong&gt; 大模型的知识被冻结在训练数据里，无法获取实时信息或私有数据。RAG通过外接知识库，让模型在生成前先「查资料」，解决了知识时效性和私有化问题。GraphRAG和LightRAG进一步引入图结构，解决复杂关系推理。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;行动能力（工具调用）：&lt;/strong&gt; 大模型本质上只是文本生成器，不能发邮件、不能查数据库、不能执行代码。Function Calling → MCP → Skill 这一套递进机制，让模型能调用外部工具，从「说话」变成「做事」。&lt;/p&gt;
&lt;p&gt;这一层对应系列第02篇（RAG）和第03篇（工具调用）。&lt;/p&gt;
&lt;h3 id="第三层应用层application产品"&gt;第三层：应用层（Application）——「产品」
&lt;/h3&gt;&lt;p&gt;有了模型、有了知识、有了工具，还需要一个&lt;strong&gt;框架把这些组件编排起来&lt;/strong&gt;，形成一个完整的AI应用。这就是LangChain、Agent和Claude Code的领域。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LangChain框架：&lt;/strong&gt; 提供标准化的组件抽象（Model I/O、Chains、Memory、Agents、Retrievers），让开发者像搭积木一样构建LLM应用。LangGraph进一步提供了多Agent编排能力。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agent智能体：&lt;/strong&gt; 终极应用形态。Agent = LLM + 工具 + 记忆 + 规划 + 反思，能自主感知环境、制定计划、调用工具、执行行动、反思纠错，形成闭环。Harness Engineering让Agent越用越聪明，Loop Engineering把编程范式从Prompt推向Loop。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Claude Code实战：&lt;/strong&gt; 一个工业级AI Coding Agent的完整拆解。从基础使用到源码架构，从系统提示词到多Agent机制，展示了Agent理论如何在真实产品中落地。&lt;/p&gt;
&lt;p&gt;这一层对应系列第04篇（LangChain）、第05篇（Agent）和第06篇（Claude Code）。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌──────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 第三层：应用层（产品） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LangChain框架 / Agent / Claude Code │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 第二层：能力层（技能） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ RAG（知识） + 工具调用（行动） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├──────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 第一层：模型层（大脑） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ LLM（Transformer/训练/推理） │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└──────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;理解了这三个层次，你就理解了整套知识体系的内在逻辑：&lt;strong&gt;从大脑（模型）到技能（RAG+工具）到产品（框架+Agent+Claude Code）&lt;/strong&gt;，每一层都建立在前一层之上。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="五贯穿全系列的十条核心原则"&gt;五、贯穿全系列的十条核心原则
&lt;/h2&gt;&lt;p&gt;在阅读后续文章时，你会发现以下原则反复出现。它们是大模型工程领域的「元认知」，理解了它们，很多具体的技术选型和设计决策都能自己推导出来：&lt;/p&gt;
&lt;h3 id="原则1模型是大脑代码是身体"&gt;原则1：模型是大脑，代码是身体
&lt;/h3&gt;&lt;p&gt;大模型永远只是「决策者」，不亲自执行任何操作。无论是Function Calling、MCP还是Agent，核心设计都是&lt;strong&gt;决策和执行分离&lt;/strong&gt;——模型决定做什么，代码负责怎么做。Claude Code的源码完美体现了这一点：模型的Query Loop负责决策，工具执行在代码层完成。&lt;/p&gt;
&lt;h3 id="原则2知识在数据里不在参数里"&gt;原则2：知识在数据里，不在参数里
&lt;/h3&gt;&lt;p&gt;大模型的知识被冻结在训练数据中。要让模型知道新知识，有两条路：RAG（外接知识库，推理时查）和微调（改参数，训练时学）。绝大多数场景下，RAG是更经济、更灵活的选择——因为知识更新只需要更新数据库，不需要重新训练模型。GraphRAG进一步证明了：用图结构组织知识，比纯向量检索更能捕捉实体间的复杂关系。&lt;/p&gt;
&lt;h3 id="原则3复杂任务必须拆分"&gt;原则3：复杂任务必须拆分
&lt;/h3&gt;&lt;p&gt;一个大模型调用做不完复杂任务。无论是Agent的任务拆分、RAG的文档切割、还是LangChain的Chain组合、Claude Code的SubAgent机制，核心思想都是&lt;strong&gt;把大问题分解为小步骤&lt;/strong&gt;，每一步让模型做它最擅长的事。&lt;/p&gt;
&lt;h3 id="原则4检索质量决定生成质量"&gt;原则4：检索质量决定生成质量
&lt;/h3&gt;&lt;p&gt;RAG系统里，Garbage In Garbage Out。如果检索到的文档不相关，模型再强也生成不出好答案。这就是为什么RAG系列会花大量篇幅讲Chunking策略、Embedding选型、Query改写、多路召回、Rerank精排——全都在优化检索质量。有趣的是，Claude Code在代码检索场景下选择了grep而非RAG——因为代码检索有精确匹配需求，这反过来说明：&lt;strong&gt;没有最好的检索方式，只有最适合场景的检索方式&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="原则5记忆是agent的连续性"&gt;原则5：记忆是Agent的连续性
&lt;/h3&gt;&lt;p&gt;没有记忆的Agent就像金鱼，每次对话都从零开始。短期记忆（context window）保持当前任务上下文，长期记忆（CLAUDE.md/向量数据库）保持跨任务的项目规范和历史。Claude Code的记忆机制设计尤其精妙：它不用向量数据库做长期记忆，而是用CLAUDE.md文件——因为代码项目的「记忆」是结构化的、可版本控制的，文件比向量更适合。&lt;/p&gt;
&lt;h3 id="原则6反思让agent从错误中学习"&gt;原则6：反思让Agent从错误中学习
&lt;/h3&gt;&lt;p&gt;优秀的Agent不是不犯错，而是犯了错能感知、能分析、能纠正。Reflection机制让Agent在每步行动后检查结果，发现异常就调整策略。Claude Code的grill-me方法论把这种反思前置——写代码前先让AI审问你的需求，这本质上是把Reflection从「事后纠错」升级为「事前预防」。&lt;/p&gt;
&lt;h3 id="原则7框架是加速器不是依赖"&gt;原则7：框架是加速器，不是依赖
&lt;/h3&gt;&lt;p&gt;LangChain、LlamaIndex等框架能帮你快速起步，但在复杂场景下框架的抽象可能成为限制。有经验的工程师知道什么时候用框架、什么时候手搓——这个判断力来自于对底层原理的理解。Claude Code本身就是一个「手搓」的Agent——它没有用LangChain，而是自己实现了Query Loop、Compact压缩、SubAgent等机制，因为通用框架无法满足AI Coding的特殊需求。&lt;/p&gt;
&lt;h3 id="原则8评估是工程化的前提"&gt;原则8：评估是工程化的前提
&lt;/h3&gt;&lt;p&gt;没有评估就没有改进。无论是RAG的检索质量评估（Hit@K、RAGAs）、还是大模型的能力评测（Benchmark+业务测试集）、还是Agent的端到端评估，量化评估是把AI从「Demo」推向「生产」的关键一环。Anthropic对40万次Claude Code会话的研究发现：用好AI编程的关键不是会写代码，而是会表达专业意图——这本身就是一种大规模评估驱动的洞察。&lt;/p&gt;
&lt;h3 id="原则9harness-engineering让agent越用越聪明"&gt;原则9：Harness Engineering让Agent越用越聪明
&lt;/h3&gt;&lt;p&gt;Agent不是一次性的工具，而是一个可以持续优化的系统。Harness Engineering的核心是：通过不断优化Agent的外围框架（Prompt模板、工具定义、记忆策略、反思机制），让同一个底层模型展现出越来越强的能力。Claude Code的CLAUDE.md、Skill机制、grill-me都是Harness Engineering的具体实践。&lt;/p&gt;
&lt;h3 id="原则10从prompt到loop是编程范式的转变"&gt;原则10：从Prompt到Loop是编程范式的转变
&lt;/h3&gt;&lt;p&gt;传统编程是「人写代码，机器执行」。AI编程的新范式是「人描述意图，AI生成代码，人审查反馈，AI修改迭代」——这是一个Loop。Loop Engineering不是简单的「让AI写代码」，而是重新定义了人机协作的编程流程：规约驱动开发（SDD）、需求审问（grill-me）、多Agent协作，都是Loop Engineering的具体模式。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="六本系列的知识来源与方法论"&gt;六、本系列的知识来源与方法论
&lt;/h2&gt;&lt;p&gt;本系列文章的素材来源于对小林面试笔记（xiaolinnote.com）七大板块共97篇深度文章的系统性遍历和完整提取：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;板块&lt;/th&gt;
&lt;th&gt;文章数&lt;/th&gt;
&lt;th&gt;核心内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;大模型面试题-Agents&lt;/td&gt;
&lt;td&gt;16篇&lt;/td&gt;
&lt;td&gt;Agent概念架构、设计范式、工程实践、多Agent协作&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;大模型面试题-RAG&lt;/td&gt;
&lt;td&gt;20篇&lt;/td&gt;
&lt;td&gt;基础概念、索引构建、检索优化、高级范式、生产落地&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;大模型面试题-工具调用&lt;/td&gt;
&lt;td&gt;16篇&lt;/td&gt;
&lt;td&gt;Function Calling、MCP、Skill、A2A、通信协议、LLM网关&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;大模型面试题-大模型工程&lt;/td&gt;
&lt;td&gt;22篇&lt;/td&gt;
&lt;td&gt;Transformer、训练、推理优化、Prompt工程、部署评测&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;大模型面试题-LangChain&lt;/td&gt;
&lt;td&gt;介绍页&lt;/td&gt;
&lt;td&gt;框架概述与生态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;图解Agent&lt;/td&gt;
&lt;td&gt;7篇&lt;/td&gt;
&lt;td&gt;Agent万字图解、OpenClaw、GraphRAG/LightRAG、Harness/Loop Engineering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;图解Claude Code&lt;/td&gt;
&lt;td&gt;16篇&lt;/td&gt;
&lt;td&gt;使用教程、Playbook实战、源码拆解、系统提示词、AI编程方法论&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;所有题目均来自字节、阿里、快手、腾讯等大厂真实面经，每道题都从根子上讲透原理。所有文章均通过带cookie的完整抓取获取，确保内容无截断。&lt;/p&gt;
&lt;p&gt;在此基础上，我们进行了以下改写和重构：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;从面试题到知识体系&lt;/strong&gt;：不再以「题」为单位，而是以「知识主题」为单位，把分散的面试题重新组织成有逻辑的知识链路。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;从问答到教程&lt;/strong&gt;：不是Q&amp;amp;A形式，而是教程式叙述，从概念引入到原理剖析到工程实践，循序渐进。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;从碎片到体系&lt;/strong&gt;：六大主题之间建立明确的关联关系，形成完整的认知框架。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;从入门到进阶&lt;/strong&gt;：每篇文章都兼顾初学者（概念清晰、类比生动）和有经验者（原理深入、工程细节、坑点提示）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;整合图解系列&lt;/strong&gt;：将图解Agent和图解Claude Code的深度内容融入相应主题，使理论有实践支撑。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="七阅读建议"&gt;七、阅读建议
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;不要跳过基础&lt;/strong&gt;。即使你已经有Agent开发经验，第01篇的Transformer原理、训练流程、推理优化也值得回顾——很多工程问题的根源就在底层原理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动手实践&lt;/strong&gt;。每篇文章中的代码示例都可以直接运行，建议边读边跑，加深理解。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关注关联&lt;/strong&gt;。注意每篇文章末尾的「与其他主题的关联」部分，这是把碎片知识串联成体系的关键。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;带着问题读&lt;/strong&gt;。每篇文章开头都有「核心问题」，读完之后检查自己能否回答这些问题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;迭代学习&lt;/strong&gt;。第一遍快速通读建立框架，第二遍深入细节，第三遍结合实践查漏补缺。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特别关注Claude Code篇&lt;/strong&gt;。即使你不做AI Coding，Claude Code的源码架构和系统提示词也是理解工业级Agent设计的最佳教材。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="八术语速查表"&gt;八、术语速查表
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;术语&lt;/th&gt;
&lt;th&gt;全称&lt;/th&gt;
&lt;th&gt;一句话解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LLM&lt;/td&gt;
&lt;td&gt;Large Language Model&lt;/td&gt;
&lt;td&gt;大语言模型，用海量文本预训练的自回归生成模型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transformer&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;大模型的核心架构，基于Self-Attention机制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAG&lt;/td&gt;
&lt;td&gt;Retrieval-Augmented Generation&lt;/td&gt;
&lt;td&gt;检索增强生成，生成前先检索外部知识&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GraphRAG&lt;/td&gt;
&lt;td&gt;Graph-based RAG&lt;/td&gt;
&lt;td&gt;图增强RAG，用知识图谱捕捉实体间复杂关系&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LightRAG&lt;/td&gt;
&lt;td&gt;Lightweight RAG&lt;/td&gt;
&lt;td&gt;轻量级图RAG，比GraphRAG更简单高效&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embedding&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;将文本映射为向量，用于语义相似度计算&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Function Calling&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;让LLM输出结构化函数调用指令的机制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;td&gt;Model Context Protocol&lt;/td&gt;
&lt;td&gt;模型上下文协议，标准化工具封装与发现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skill&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;任务流程知识化，把操作步骤打包成可复用模块&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A2A&lt;/td&gt;
&lt;td&gt;Agent-to-Agent&lt;/td&gt;
&lt;td&gt;Agent间协作协议&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;能自主完成目标的AI系统&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ReAct&lt;/td&gt;
&lt;td&gt;Reasoning + Acting&lt;/td&gt;
&lt;td&gt;推理+行动交替的Agent设计范式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CoT&lt;/td&gt;
&lt;td&gt;Chain-of-Thought&lt;/td&gt;
&lt;td&gt;思维链，让模型逐步推理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KV Cache&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;推理时缓存注意力Key-Value矩阵以加速&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LoRA&lt;/td&gt;
&lt;td&gt;Low-Rank Adaptation&lt;/td&gt;
&lt;td&gt;低秩适配，高效的微调方法&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MoE&lt;/td&gt;
&lt;td&gt;Mixture of Experts&lt;/td&gt;
&lt;td&gt;混合专家模型，总参数大但激活参数小&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LCEL&lt;/td&gt;
&lt;td&gt;LangChain Expression Language&lt;/td&gt;
&lt;td&gt;LangChain表达式语言&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangGraph&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;LangChain的图式编排运行时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangSmith&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;LangChain的可观测性平台&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SFT&lt;/td&gt;
&lt;td&gt;Supervised Fine-Tuning&lt;/td&gt;
&lt;td&gt;监督微调&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RLHF&lt;/td&gt;
&lt;td&gt;Reinforcement Learning from Human Feedback&lt;/td&gt;
&lt;td&gt;基于人类反馈的强化学习&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DPO&lt;/td&gt;
&lt;td&gt;Direct Preference Optimization&lt;/td&gt;
&lt;td&gt;直接偏好优化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PPO&lt;/td&gt;
&lt;td&gt;Proximal Policy Optimization&lt;/td&gt;
&lt;td&gt;近端策略优化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLAUDE.md&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Claude Code的项目记忆文件，定义项目规范和上下文&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Harness Engineering&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Agent外围框架工程，让Agent越用越聪明&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loop Engineering&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;从Prompt到Loop的AI编程范式转变&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDD&lt;/td&gt;
&lt;td&gt;Spec-Driven Development&lt;/td&gt;
&lt;td&gt;规约驱动开发，先规约后编码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;grill-me&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;写代码前先让AI审问需求的方法论&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SubAgent&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Claude Code的子Agent机制，用于并行任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compact&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Claude Code的上下文压缩机制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenClaw&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;开源Agent框架/方法论&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fable 5&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Claude的系统提示词版本代号&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;下一篇：&lt;a class="link" href="01_%e5%a4%a7%e6%a8%a1%e5%9e%8b%e5%9f%ba%e7%a1%80%e4%b8%8e%e5%b7%a5%e7%a8%8b%e5%8c%96%e5%ae%9e%e8%b7%b5.md" &gt;01 大模型基础与工程化实践&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我们将从Transformer架构出发，一路讲到训练三阶段、推理优化、Prompt工程和部署评测，建立对大模型本身的最底层理解。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;本文是「AI知识成长体系」系列第00篇。全系列共8篇，形成完整的大模型工程知识成长体系。&lt;/em&gt;&lt;/p&gt;</description></item><item><title>第19章：大模型评估与测试——怎么知道你的 AI 系统好还是不好？</title><link>https://blog.irudder.me/ai/knowledge-series/19-LLM-Evaluation-and-Testing.html</link><pubDate>Wed, 22 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/19-LLM-Evaluation-and-Testing.html</guid><description>&lt;h1 id="第19章大模型评估与测试怎么知道你的-ai-系统好还是不好"&gt;第19章：大模型评估与测试——怎么知道你的 AI 系统好还是不好？
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：&amp;ldquo;感觉不错&amp;quot;不是一个好的评估标准。本章教你建立一套可复现、可量化、可迭代的评估体系。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一为什么评估很重要"&gt;一、为什么评估很重要？
&lt;/h2&gt;&lt;p&gt;你改了一个 Prompt、换了一个模型、加了一个工具——&lt;strong&gt;效果到底变好了还是变差了？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;没有评估体系，你就只能凭感觉。而&amp;quot;感觉&amp;quot;在实际工程中往往是错的，因为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;幻觉的答案听起来可能很有道理&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型在某些问题上碰巧答对了，不代表整体变好了&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不同批次、不同负载下的表现波动很大&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="二评估的三个维度"&gt;二、评估的三个维度
&lt;/h2&gt;&lt;p&gt;把 LLM 系统的评估拆成三个层面：&lt;/p&gt;
&lt;h3 id="维度1输出质量"&gt;维度1：输出质量
&lt;/h3&gt;&lt;p&gt;回答的内容是否正确、有用、完整？&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指标&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;怎么测&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;准确率&lt;/td&gt;
&lt;td&gt;事实性问题答对的占比&lt;/td&gt;
&lt;td&gt;标注事实问答对，跑批量测试&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;相关性&lt;/td&gt;
&lt;td&gt;回答是否针对用户问题&lt;/td&gt;
&lt;td&gt;人工打分 / LLM-as-Judge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;完整性&lt;/td&gt;
&lt;td&gt;是否覆盖了问题的所有方面&lt;/td&gt;
&lt;td&gt;检查清单覆盖度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;幻觉率&lt;/td&gt;
&lt;td&gt;编造信息的出现频率&lt;/td&gt;
&lt;td&gt;人工抽查 / 和知识库交叉验证&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;一致性&lt;/td&gt;
&lt;td&gt;同问法不同表述，输出是否一致&lt;/td&gt;
&lt;td&gt;改写问句重复测试&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="维度2推理质量"&gt;维度2：推理质量
&lt;/h3&gt;&lt;p&gt;Agent 的推理过程是否正确？&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指标&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;怎么测&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;工具选择准确率&lt;/td&gt;
&lt;td&gt;选的工具对不对&lt;/td&gt;
&lt;td&gt;标注每个场景应调用的工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;参数准确率&lt;/td&gt;
&lt;td&gt;传的参数对不对&lt;/td&gt;
&lt;td&gt;参数值和期望值的匹配度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;终止条件达成率&lt;/td&gt;
&lt;td&gt;任务是否结束在正确状态&lt;/td&gt;
&lt;td&gt;检查最终输出是否回答完问题&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;循环检测&lt;/td&gt;
&lt;td&gt;是否陷入死循环（反复调用同一工具）&lt;/td&gt;
&lt;td&gt;监控调用次数和去重&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="维度3系统性能"&gt;维度3：系统性能
&lt;/h3&gt;&lt;p&gt;速度、成本、稳定性&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指标&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;目标值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;首 token 延迟&lt;/td&gt;
&lt;td&gt;从提问到第一个输出生成的时间&lt;/td&gt;
&lt;td&gt;&amp;lt;1s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;吞吐率&lt;/td&gt;
&lt;td&gt;每分钟处理请求数&lt;/td&gt;
&lt;td&gt;按业务需求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Token 消耗&lt;/td&gt;
&lt;td&gt;每次调用的平均 token 数&lt;/td&gt;
&lt;td&gt;越低越好&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;错误率&lt;/td&gt;
&lt;td&gt;API 调用失败 / 超时 / 异常的占比&lt;/td&gt;
&lt;td&gt;&amp;lt;0.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;并发能力&lt;/td&gt;
&lt;td&gt;同时处理的最大请求数&lt;/td&gt;
&lt;td&gt;按 SLA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="三llm-as-judge用模型来评估模型"&gt;三、LLM-as-Judge：用模型来评估模型
&lt;/h2&gt;&lt;p&gt;让 GPT-4 来评分你的 GPT-3.5 输出——这是目前最火的自动化评估手段。&lt;/p&gt;
&lt;h3 id="思路"&gt;思路
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;评估 Prompt：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;#34;以下是用户的问题和模型生成的答案。请从以下几个方面打分（1-5分）：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. 准确性：答案中的事实是否正确？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. 完整性：答案是否覆盖了用户的所有问题？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. 有用性：答案对用户是否有实际帮助？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. 安全性：答案是否有有害内容？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户问题：{question}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;模型答案：{answer}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;参考答案：{golden_answer}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;请输出 JSON 格式的评分。&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="局限性"&gt;局限性
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;评分者偏见&lt;/strong&gt;：GPT-4 可能偏好某些风格（比如长回答）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;对事实问题判断不准&lt;/strong&gt;：LLM 自己也会幻觉，用它评估事实准确性有风险&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;对复杂推理评价弱&lt;/strong&gt;：LLM 不一定能判断复杂推理链的正确性&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;黄金法则&lt;/strong&gt;：LLM-as-Judge 适合做筛选和初步分级，最终重要决策仍需人工审核。&lt;/p&gt;
&lt;h2 id="四建立-golden-set黄金评估集"&gt;四、建立 Golden Set（黄金评估集）
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Golden Set 是一组人工标注的高质量&amp;quot;问题-期望答案&amp;quot;对&lt;/strong&gt;，是评估的基石。&lt;/p&gt;
&lt;h3 id="golden-set-建集原则"&gt;Golden Set 建集原则
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;覆盖核心场景&lt;/strong&gt;：涵盖你的 Agent 最常见的 10-20 类问题&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标注&amp;quot;完整期望&amp;rdquo;&lt;/strong&gt;：不仅标对/错，还要标&amp;quot;好的回答长什么样&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;包含边界案例&lt;/strong&gt;：边缘输入、模糊问题、歧义问题&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定期更新&lt;/strong&gt;：Agent 迭代、业务变化后，golden set 也要跟进&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="规模建议"&gt;规模建议
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent 复杂度&lt;/th&gt;
&lt;th&gt;Golden Set 大小&lt;/th&gt;
&lt;th&gt;覆盖度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;简单问答 Agent&lt;/td&gt;
&lt;td&gt;20-50 条&lt;/td&gt;
&lt;td&gt;主要场景&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;多工具 Agent&lt;/td&gt;
&lt;td&gt;50-200 条&lt;/td&gt;
&lt;td&gt;核心路径 + 分支&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-Agent 系统&lt;/td&gt;
&lt;td&gt;100-500 条&lt;/td&gt;
&lt;td&gt;全链路场景&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="五评估系统的自动化跑通"&gt;五、评估系统的自动化跑通
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;每次迭代（改 Prompt / 换模型 / 加工具）：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. 在 Golden Set 上跑完整评测
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. 生成评估报告（准确度、幻觉率、延迟）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. 对比上个版本的 diff
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. regression 检测：有没有之前对的问题现在错了？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5. 决定是否合并到主分支
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="六本章小结"&gt;六、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;评估分三层：输出质量 + 推理质量 + 系统性能&lt;/li&gt;
&lt;li&gt;LLM-as-Judge 是自动化评估的有效工具，但不能取代人工审核&lt;/li&gt;
&lt;li&gt;Golden Set 是评估根基，要覆盖主要场景和边界案例&lt;/li&gt;
&lt;li&gt;每次修改都跑回归测试，防止&amp;quot;修好一个问题，坏掉另一个&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;LLM-as-Judge 的打分结果和标准评分的 Correlation（相关性）一般有多少？怎么验证你的 LLM-as-Judge 是靠谱的？&lt;/li&gt;
&lt;li&gt;如果你发现每次改了某处后，Golden Set 里有 3 条本来对的问题现在错了，但同时有 5 条之前有问题的现在好了——你怎么决定要不要合并这个改动？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第17章：推理优化——KV Cache、量化与高效生成</title><link>https://blog.irudder.me/ai/knowledge-series/17-Inference-Optimization-and-KV-Cache.html</link><pubDate>Fri, 17 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/17-Inference-Optimization-and-KV-Cache.html</guid><description>&lt;h1 id="第17章推理优化kv-cache量化与高效生成"&gt;第17章：推理优化——KV Cache、量化与高效生成
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：本章是 LLM 工程的核心技术之一。如果你要自建 LLM 服务或做推理调优，KV Cache 是必须理解的第一块基础。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一llm-推理有多贵"&gt;一、LLM 推理有多贵？
&lt;/h2&gt;&lt;p&gt;GPT-4 处理一个 4000 token 的文档 + 生成 500 token 的答案，单次调用的推理成本是多少？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prompt token&lt;/strong&gt;：每 token 都有成本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成的每个 token&lt;/strong&gt;：都要做一次完整的模型前向传播&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;长上下文&lt;/strong&gt;：注意力计算是 O(n²)，token 越多越慢&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;高频服务的推理成本会是最大的运营开销。优化不是锦上添花，是生死线。&lt;/p&gt;
&lt;h2 id="二kv-cache为什么解码慢"&gt;二、KV Cache：为什么解码慢？
&lt;/h2&gt;&lt;p&gt;Transformer 在生成时有一个核心特性：&lt;strong&gt;自回归生成&lt;/strong&gt;——每次只能生成一个 token。&lt;/p&gt;
&lt;p&gt;假设你在生成第 K 个 token，模型需要：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;把所有之前的 token 重新过一遍（包括你刚生成的第 K-1 个）&lt;/li&gt;
&lt;li&gt;计算所有 token 的 Key 和 Value 向量&lt;/li&gt;
&lt;li&gt;用这些 KV 做注意力，生成第 K 个 token&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;重复计算极大浪费&lt;/strong&gt;。前面的 token 的 Key 和 Value 计算结果，在第 100 步和第 101 步怎么可能变？&lt;/p&gt;
&lt;h3 id="kv-cache-的核心思想"&gt;KV Cache 的核心思想
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;缓存历史 token 的 Key 和 Value 向量，每步只计算新 token 的 KV。&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 没有 KV Cache（每次全量计算）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_new_tokens&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;full_input&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;generated_tokens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# O(n²) 的注意力&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;next_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;generated_tokens&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 有 KV Cache（只计算新内容）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_new_tokens&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 只输入最新一个 token，KV Cache 提供历史注意力&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;past_key_values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;kv_cache&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;kv_cache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 新 token 的 KV 加入缓存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;next_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="效果"&gt;效果
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;时间复杂度：从 O(n²) → O(n)（每个新 token 的计算量几乎恒定）&lt;/li&gt;
&lt;li&gt;速度提升：长上下文时提升数倍&lt;/li&gt;
&lt;li&gt;内存消耗：需要额外存储所有历史 KV（通常几百 MB 到几 GB）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="kv-cache-的容量压力"&gt;KV Cache 的容量压力
&lt;/h3&gt;&lt;p&gt;KV Cache 的大小 = 层数 × 注意力头数 × 序列长度 × 每头维度 × 2 (K+V) × 每个值精度&lt;/p&gt;
&lt;p&gt;以 LLaMA-2-70B 为例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;80 层 × 8 KV 头 × 序列长度 4096 × 128 维度 × 2 × 2 bytes (FP16)&lt;/li&gt;
&lt;li&gt;≈ &lt;strong&gt;160 GB 内存&lt;/strong&gt; 才能存放一个 batch_size=1 的 KV Cache&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就是为什么 &lt;strong&gt;长上下文 + 大 batch_size&lt;/strong&gt; 的 LLM 推理内存需求极高。&lt;/p&gt;
&lt;h2 id="三量化推理quantization"&gt;三、量化推理（Quantization）
&lt;/h2&gt;&lt;p&gt;模型推理时的参数量极大（GPT-3 175B → ~350GB FP16），加载到 GPU 需要巨量显存。&lt;/p&gt;
&lt;p&gt;量化：把模型权重从高精度（FP16/32）压缩到低精度（INT8/INT4），降低内存占用和计算带宽需求。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;精度&lt;/th&gt;
&lt;th&gt;每参数占存&lt;/th&gt;
&lt;th&gt;效果影响&lt;/th&gt;
&lt;th&gt;适用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FP32&lt;/td&gt;
&lt;td&gt;4 bytes&lt;/td&gt;
&lt;td&gt;基准&lt;/td&gt;
&lt;td&gt;训练&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FP16/BF16&lt;/td&gt;
&lt;td&gt;2 bytes&lt;/td&gt;
&lt;td&gt;几乎无损&lt;/td&gt;
&lt;td&gt;推理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INT8&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;轻微损失&lt;/td&gt;
&lt;td&gt;推理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INT4&lt;/td&gt;
&lt;td&gt;0.5 bytes&lt;/td&gt;
&lt;td&gt;可观测损失&lt;/td&gt;
&lt;td&gt;边缘/消费级&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPTQ/AWQ&lt;/td&gt;
&lt;td&gt;INT4 级&lt;/td&gt;
&lt;td&gt;优化后接近 INT8&lt;/td&gt;
&lt;td&gt;本地推理&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="gptq--awq--gguf"&gt;GPTQ / AWQ / GGUF
&lt;/h3&gt;&lt;p&gt;这些是在 INT4 量级上做的高级量化技术，核心改进是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPTQ&lt;/strong&gt;：基于二阶 Hessian 信息做分组量化，误差更小&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWQ&lt;/strong&gt;：观察到&amp;quot;权重中 1% 离群值对效果影响极大&amp;quot;，对离群值保持高精度&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GGUF&lt;/strong&gt;：llama.cpp 的格式，CPU 推理友好，消费级 GPU 也能跑大模型&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="四pagedattention-与-vllm"&gt;四、PagedAttention 与 vLLM
&lt;/h2&gt;&lt;p&gt;除了 KV Cache 和量化，还有一个革命性的推理优化：&lt;strong&gt;PagedAttention&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="问题kv-cache-的内存碎片"&gt;问题：KV Cache 的内存碎片
&lt;/h3&gt;&lt;p&gt;系统同时服务多个请求，每个请求的序列长度不同。显存分配像内存分配一样，会产生碎片。&lt;/p&gt;
&lt;p&gt;传统做法：每个请求预分配最大可能的 KV Cache 空间 → 大量内存浪费。&lt;/p&gt;
&lt;h3 id="pagedattention-的思路"&gt;PagedAttention 的思路
&lt;/h3&gt;&lt;p&gt;借鉴操作系统虚拟内存的&lt;strong&gt;分页机制&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把 KV Cache 切成固定大小的 &amp;ldquo;block&amp;rdquo;（比如 16 token 一组 KV）&lt;/li&gt;
&lt;li&gt;按需要的块动态分配和回收&lt;/li&gt;
&lt;li&gt;用 block table 做虚拟到物理的映射&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;效果&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内存碎片化几乎消除&lt;/li&gt;
&lt;li&gt;batch size 可以提升数倍&lt;/li&gt;
&lt;li&gt;吞吐量提升 3-5 倍（论文数据）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;vLLM&lt;/strong&gt;：基于 PagedAttention 的高性能推理引擎，是自建 LLM 服务的首选开源框架。&lt;/p&gt;
&lt;h2 id="五推理优化的决策树"&gt;五、推理优化的决策树
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;你要优化推理？先看你的瓶颈：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;内存不够？ → 量化（FP16→INT8或INT4）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;速度不够？ → KV Cache + PagedAttention (vLLM)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;并发不够？ → 批处理优化（continuous batching）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;长上下文慢？ → KV Cache + 稀疏注意力 / 滑动窗口注意力
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;网络延迟？ → 流式输出（SSE）+ 输出压缩
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="六本章小结"&gt;六、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;KV Cache 是 LLM 推理加速的第一性原理：避免重复计算历史 token&lt;/li&gt;
&lt;li&gt;KV Cache 的内存消耗极大，是大 batch / 长上下文推理的主要瓶颈&lt;/li&gt;
&lt;li&gt;量化（FP16/INT8/INT4）是压缩模型体积的最有效手段&lt;/li&gt;
&lt;li&gt;PagedAttention 用分页管理 KV Cache，消除碎片、提升吞吐量&lt;/li&gt;
&lt;li&gt;vLLM 结合了 KV Cache + PagedAttention + 高效调度，是当前主流的高性能推理方案&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;KV Cache 的内存占用和 batch_size 成正比。如果要在单卡 24GB 显存上实现比较大的并发，你会从哪些角度做取舍设计？&lt;/li&gt;
&lt;li&gt;量化到 INT4 后精度损失最大的是哪些类型的权重？为什么 Transformer 的注意力层权重比较敏感？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第15章：LangChain 框架——Agent 开发的瑞士军刀</title><link>https://blog.irudder.me/ai/knowledge-series/15-LangChain-Framework-Practical-Guide.html</link><pubDate>Fri, 10 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/15-LangChain-Framework-Practical-Guide.html</guid><description>&lt;h1 id="第15章langchain-框架agent-开发的瑞士军刀"&gt;第15章：LangChain 框架——Agent 开发的瑞士军刀
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：LangChain 是 Agent 开发的主流框架。本章讲框架架构、核心概念和实战决策——&amp;ldquo;什么时候用 LangChain，什么时候应该甩开它&amp;rdquo;。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一langchain-要解决的问题"&gt;一、LangChain 要解决的问题
&lt;/h2&gt;&lt;p&gt;手工实现一个 Agent，你需要写：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tool 注册与解析&lt;/li&gt;
&lt;li&gt;Prompt 模板管理&lt;/li&gt;
&lt;li&gt;Memory 存储维护&lt;/li&gt;
&lt;li&gt;Agent 循环逻辑（ReAct / Plan-and-Execute）&lt;/li&gt;
&lt;li&gt;错误处理和重试&lt;/li&gt;
&lt;li&gt;多 Agent 协作（如果需要）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;LangChain 把这些都封装成了可复用的组件和链式工具，让 Agent 开发从&amp;quot;从零搭建&amp;quot;变成&amp;quot;组装积木&amp;quot;。&lt;/p&gt;
&lt;h2 id="二langchain-核心概念"&gt;二、LangChain 核心概念
&lt;/h2&gt;&lt;h3 id="1-chain链"&gt;1. Chain（链）
&lt;/h3&gt;&lt;p&gt;将多个组件按顺序串起来执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt_template&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;output_parser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;分析这份数据&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;每个 | 表示前一个组件的输出经过变换传给下一个组件。&lt;/p&gt;
&lt;h3 id="2-agent"&gt;2. Agent
&lt;/h3&gt;&lt;p&gt;预先封装好的 Agent 循环：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_react_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent_executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AgentExecutor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_iterations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent_executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;帮我查天气&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;预置的 Agent 类型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReAct Agent：Thought → Action → Observation 循环&lt;/li&gt;
&lt;li&gt;Plan-and-Execute Agent：先规划计划，再按步骤执行&lt;/li&gt;
&lt;li&gt;Structured Chat Agent：支持多参数工具调用&lt;/li&gt;
&lt;li&gt;Conversational Agent：带记忆的对话型 Agent&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-tool"&gt;3. Tool
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;查询指定城市的天气信息。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;今天天气晴朗，25度&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;装饰自动提取函数签名和 docstring 作为 tool schema，非常简洁。&lt;/p&gt;
&lt;h3 id="4-memory"&gt;4. Memory
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain.memory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ConversationBufferMemory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConversationBufferMemory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save_context&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;我喜欢简洁风格&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;output&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;好的，我会注意&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# memory 会自动维护对话历史，在 Agent 调用时作为 context 注入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="5-retriever检索器"&gt;5. Retriever（检索器）
&lt;/h3&gt;&lt;p&gt;把 RAG 的检索部分封装好：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;什么是 RAG？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="三langchain-的优势"&gt;三、LangChain 的优势
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;快速原型&lt;/strong&gt;：组装积木的方式，几小时就能跑通一个 Agent&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生态丰富&lt;/strong&gt;：内置大量 ready-to-use 的 tools、retrievers、memory 模块&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标准接口&lt;/strong&gt;：统一的 invoke/stream/batch 接口，切换底层模型无痛&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;调试友好&lt;/strong&gt;：链式调用的中间步骤都能打印出来&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="四langchain-的天坑"&gt;四、LangChain 的天坑
&lt;/h2&gt;&lt;h3 id="坑1过度封装"&gt;坑1：过度封装
&lt;/h3&gt;&lt;p&gt;LangChain 的链式抽象堆了太多层，理解一个简单调用背后实际发生了什么，需要追踪好几层源码。&lt;/p&gt;
&lt;h3 id="坑2性能问题"&gt;坑2：性能问题
&lt;/h3&gt;&lt;p&gt;链式调用每层都有类型转换、验证、异常捕获，对高频场景来说有不可忽视的 overhead。&lt;/p&gt;
&lt;h3 id="坑3版本迭代快"&gt;坑3：版本迭代快
&lt;/h3&gt;&lt;p&gt;API 变动频繁，一个用 v0.1 写的项目，几个月后 v0.2 就 break。&lt;/p&gt;
&lt;h3 id="坑4不适合深度定制"&gt;坑4：不适合深度定制
&lt;/h3&gt;&lt;p&gt;你要做一个高度定制的推理流程，LangChain 的约束框架可能碍手碍脚。&lt;/p&gt;
&lt;h2 id="五什么时候用-langchain什么时候手搓"&gt;五、&amp;ldquo;什么时候用 LangChain，什么时候手搓？&amp;rdquo;
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;推荐方案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;快速原型验证 / MVP&lt;/td&gt;
&lt;td&gt;用 LangChain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;标准 Agent 模式（ReAct、工具调用）&lt;/td&gt;
&lt;td&gt;用 LangChain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内部工具/低频应用&lt;/td&gt;
&lt;td&gt;用 LangChain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;高并发生产服务&lt;/td&gt;
&lt;td&gt;手搓核心关键路径&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;极度定制化的推理流程&lt;/td&gt;
&lt;td&gt;手搓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;需要极致性能优化&lt;/td&gt;
&lt;td&gt;手搓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;大规模 Multi-Agent 系统&lt;/td&gt;
&lt;td&gt;手搓核心编排，局部用框架&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;最务实的做法&lt;/strong&gt;：用 LangChain 快速做出 MVP，验证业务价值后再决定哪些部分需要重写。&lt;/p&gt;
&lt;h2 id="六langchain-实战一个完整的-rag-agent"&gt;六、LangChain 实战：一个完整的 RAG Agent
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_chroma&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_community.document_loaders&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;WebBaseLoader&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_text_splitters&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.runnables&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. 加载文档&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebBaseLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://docs.python.org/3/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. 切割&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;text_splitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk_overlap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;splits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text_splitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. 存入向量库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vectorstore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;splits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. 构建 RAG Chain&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;rlm/rag-prompt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;format_docs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;rag_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;context&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;format_docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RunnablePassthrough&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 5. 使用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rag_chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Python 的 GIL 是什么？&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="七langchain-的替代者"&gt;七、LangChain 的替代者
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;框架&lt;/th&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LangGraph&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LangChain 官方出的图编排工具，比链更灵活&lt;/td&gt;
&lt;td&gt;复杂 Multi-Agent 编排&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LlamaIndex&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;专注 RAG，文档加载和索引更强&lt;/td&gt;
&lt;td&gt;知识库/文档问答&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CrewAI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;专注 Multi-Agent 协作场景&lt;/td&gt;
&lt;td&gt;多智能体项目&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AutoGen&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;微软出的 Multi-Agent 对话框架&lt;/td&gt;
&lt;td&gt;研究/多轮讨论&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;直接 SDK&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;不用框架，直接调 OpenAI/Anthropic SDK&lt;/td&gt;
&lt;td&gt;简单/高性能场景&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="八本章小结"&gt;八、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;LangChain 是 Agent/RAG 快速开发和原型验证的首选框架&lt;/li&gt;
&lt;li&gt;核心概念：Chain、Agent、Tool、Memory、Retriever&lt;/li&gt;
&lt;li&gt;优势是组装敏捷和生态丰富，劣势是过度封装和性能开销&lt;/li&gt;
&lt;li&gt;选型建议：MVP 用 LangChain，生产级核心路径可重写&lt;/li&gt;
&lt;li&gt;LlamaIndex（RAG 更强）、CrewAI（Multi-Agent 更强）是重要替代方案&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;你在什么情况下会用 LlamaIndex 而不是 LangChain？两个框架的核心差异在哪？&lt;/li&gt;
&lt;li&gt;如果你的 Agent 需要同时走 &amp;ldquo;向量检索 + API 调用 + 代码执行 + 最终报告生成&amp;rdquo; 四条路径，LangChain 的链式抽象够用吗？你会怎么设计架构？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第14章：Agent 记忆系统——如何让 AI 记得你的约定？</title><link>https://blog.irudder.me/ai/knowledge-series/14-Agent-Memory-System.html</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/14-Agent-Memory-System.html</guid><description>&lt;h1 id="第14章agent-记忆系统如何让-ai-记得你的约定"&gt;第14章：Agent 记忆系统——如何让 AI 记得你的约定？
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：记忆是 Agent 区别于单次对话 LLM 的核心特征之一。没有记忆，Agent 每次对话都像第一次认识。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一没有记忆的-agent-有多不好用"&gt;一、没有记忆的 Agent 有多不好用？
&lt;/h2&gt;&lt;p&gt;想象这个场景：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你：帮我分析这份 Excel 里的销售数据，只关注华东地区。
Agent：好的，分析完成，华东地区销售增长 12%。&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;你（过了一小时，新开了一个对话）：上面的分析结果出了报告吗？
Agent：抱歉，我不记得之前的对话&amp;hellip;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;这就是没有记忆的代价&lt;/strong&gt;——Agent 无法跨任务保持连贯性，无法积累对你的了解。&lt;/p&gt;
&lt;h2 id="二记忆的四层架构"&gt;二、记忆的四层架构
&lt;/h2&gt;&lt;h3 id="layer-1感知记忆sensory-memory"&gt;Layer 1：感知记忆（Sensory Memory）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内容&lt;/strong&gt;：当前输入的原始内容（用户说的话、上传的文件、语音转文字）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;存储&lt;/strong&gt;：内存，即时处理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生命周期&lt;/strong&gt;：处理完就丢弃&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="layer-2短期记忆short-term-memory"&gt;Layer 2：短期记忆（Short-term Memory）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内容&lt;/strong&gt;：当前任务的对话历史、中间推理过程、工具执行结果&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;存储&lt;/strong&gt;：LLM 的 context window&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生命周期&lt;/strong&gt;：当前任务结束后即可清理&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="layer-3长期记忆long-term-memory"&gt;Layer 3：长期记忆（Long-term Memory）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内容&lt;/strong&gt;：跨会话的知识、用户偏好、历史决策、积累的经验&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;存储&lt;/strong&gt;：向量数据库、关系型数据库&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生命周期&lt;/strong&gt;：持续存在，可更新&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="layer-4实体记忆entity-memory"&gt;Layer 4：实体记忆（Entity Memory）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内容&lt;/strong&gt;：从对话中提炼的结构化事实（&amp;ldquo;张三喜欢 Java&amp;rdquo;、&amp;ldquo;项目预算500万&amp;rdquo;）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;存储&lt;/strong&gt;：键值对存储、图数据库&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生命周期&lt;/strong&gt;：持续存在，可修正和合并&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="三短期记忆设计"&gt;三、短期记忆设计
&lt;/h2&gt;&lt;p&gt;短期记忆就是 context window 里维护的对话历史。核心问题是：&lt;strong&gt;context 有限，满了之后怎么办？&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="方案1滑动窗口"&gt;方案1：滑动窗口
&lt;/h3&gt;&lt;p&gt;只保留最近的 N 轮对话，更老的丢弃。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;max_context_length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 保留系统 prompt + 最新的 N 条&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;system_message&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;max_history&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：简单、易实现
&lt;strong&gt;缺点&lt;/strong&gt;：30分钟前一个技术决策说砍就砍，Agent 开始忘事&lt;/p&gt;
&lt;h3 id="方案2摘要压缩"&gt;方案2：摘要压缩
&lt;/h3&gt;&lt;p&gt;当历史太长时，让 LLM 把旧对话摘要成简短总结。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;原始历史（20轮）→ LLM 摘要 → 3句话总结
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;#34;用户要求分析华东销售数据，分析了Q1-Q3增长趋势，确认重点产品线是 A 和 B&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：保留关键信息
&lt;strong&gt;缺点&lt;/strong&gt;：摘要可能丢细节；有额外 LLM 调用成本&lt;/p&gt;
&lt;h3 id="方案3重要性过滤"&gt;方案3：重要性过滤
&lt;/h3&gt;&lt;p&gt;给每条对话打分，只保留高重要性的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;打分方式&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;规则式：包含&amp;quot;决定&amp;quot;&amp;ldquo;确认&amp;quot;&amp;ldquo;方案&amp;quot;等关键词的权重高&lt;/li&gt;
&lt;li&gt;模型式：用一个小模型判断某条信息的重要性&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="四长期记忆设计"&gt;四、长期记忆设计
&lt;/h2&gt;&lt;h3 id="向量存储语义记忆"&gt;向量存储（语义记忆）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;把有价值的信息做 embedding，存入向量库&lt;/li&gt;
&lt;li&gt;检索时用语义匹配，召回相关历史&lt;/li&gt;
&lt;li&gt;适合：用户偏好、通用知识、经验总结&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;User: &amp;#34;我喜欢简洁风格的代码，不要过度注释&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;提取关键信息 → embedding → 存入向量库
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tag: &amp;#34;用户偏好&amp;#34;, &amp;#34;代码风格&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="结构化存储实体记忆"&gt;结构化存储（实体记忆）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;用键值对或图数据库存储提炼的事实&lt;/li&gt;
&lt;li&gt;适合：具体事实（&amp;ldquo;服务器 IP 是 xx&amp;rdquo;、&amp;ldquo;项目截止日期 yy&amp;rdquo;）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;entities&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;user_preferences&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;coding_style&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;简洁，少注释&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;communication&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;中文&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;detail_level&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;high&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;project_facts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;server_ip&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;10.0.1.12&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;deadline&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2026-08-15&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="记忆的存取时机"&gt;记忆的&amp;quot;存取&amp;quot;时机
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;什么时候存？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户明确提出偏好&lt;/li&gt;
&lt;li&gt;讨论了重要决策/结论&lt;/li&gt;
&lt;li&gt;任务完成后总结的经验&lt;/li&gt;
&lt;li&gt;检测到首次出现的有意义新信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;什么时候取？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每次新任务启动时，检索相关历史背景&lt;/li&gt;
&lt;li&gt;任务中途遇到不确定信息时，回忆之前的约定&lt;/li&gt;
&lt;li&gt;生成回答前，检查是否有已知的用户偏好&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="五记忆系统设计核心原则"&gt;五、记忆系统设计核心原则
&lt;/h2&gt;&lt;h3 id="1-存什么取舍"&gt;1. 存什么？（取舍）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;不是什么都存 → context 爆炸、检索噪音&lt;/li&gt;
&lt;li&gt;只存&amp;quot;有长久价值的信息&amp;rdquo;：偏好、约定、事实、经验&lt;/li&gt;
&lt;li&gt;临时中间结果（如一次搜索的中间页面）不存&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-怎么存粒度"&gt;2. 怎么存？（粒度）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;太细碎 → 检索噪音大，拿到碎片化信息&lt;/li&gt;
&lt;li&gt;太粗略 → 关键细节丢失&lt;/li&gt;
&lt;li&gt;推荐：以&amp;quot;一次完整交互&amp;quot;或&amp;quot;一个关键决策&amp;quot;为单位&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-什么时候取时机"&gt;3. 什么时候取？（时机）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;主动检索：任务开始前基于关键词召回&lt;/li&gt;
&lt;li&gt;按需检索：遇到不确定信息时（&amp;ldquo;等等，用户之前好像说过&amp;hellip;&amp;quot;）&lt;/li&gt;
&lt;li&gt;不要太勤快：每步都查记忆 → 延迟增加&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="六记忆压缩技术"&gt;六、记忆压缩技术
&lt;/h2&gt;&lt;p&gt;当长期记忆库越来越大，怎么解决？&lt;/p&gt;
&lt;h3 id="摘要聚合"&gt;摘要聚合
&lt;/h3&gt;&lt;p&gt;把一段时间内的多条记录用 LLM 摘要合并：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;记录1: &amp;#34;用户喜欢 Go 语言&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;记录2: &amp;#34;用户用 Go 写过微服务&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;记录3: &amp;#34;用户说我写的 Go 代码风格不对&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;摘要: &amp;#34;用户是 Go 开发者，注重代码规范，可参考 gofmt 标准&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="过期遗忘"&gt;过期遗忘
&lt;/h3&gt;&lt;p&gt;给记忆设 TTL（生存时间），比如一条技能偏好半年没用到就删除。&lt;/p&gt;
&lt;h3 id="合并去重"&gt;合并去重
&lt;/h3&gt;&lt;p&gt;新记录写进去前，先检索是否已有类似记录，有就合并更新。&lt;/p&gt;
&lt;h2 id="七本章小结"&gt;七、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;记忆系统解决 Agent 的&amp;quot;失忆&amp;quot;问题，让它能跨任务积累知识&lt;/li&gt;
&lt;li&gt;四层记忆：感知 → 短期（context）→ 长期（向量库）→ 实体（结构化）&lt;/li&gt;
&lt;li&gt;短期记忆要处理 context 溢出：滑动窗口、摘要、重要性过滤&lt;/li&gt;
&lt;li&gt;长期记忆的存取是&amp;quot;存什么、怎么存、什么时候取&amp;quot;三个核心决策&lt;/li&gt;
&lt;li&gt;记忆不是越多越好，取舍和时效管理同样重要&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;如果让你设计一个&amp;quot;VIP 用户记忆系统&amp;rdquo;（要求记住优先级用户的长期偏好和行为模式），你会在哪些维度上加强？&lt;/li&gt;
&lt;li&gt;长期记忆如果出现了矛盾信息（用户上周说喜欢 A，这周说喜欢 B），系统该怎么处理？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第12章：Agent 推理模式——从 CoT 到 ReAct 再到自主执行</title><link>https://blog.irudder.me/ai/knowledge-series/12-Agent-Reasoning-Patterns-and-ReAct.html</link><pubDate>Fri, 26 Jun 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/12-Agent-Reasoning-Patterns-and-ReAct.html</guid><description>&lt;h1 id="第12章agent-推理模式从-cot-到-react-再到自主执行"&gt;第12章：Agent 推理模式——从 CoT 到 ReAct 再到自主执行
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：本章深入 Agent 的&amp;quot;思考方式&amp;quot;，是它之所以&amp;quot;智能&amp;quot;的核心机制。理解了推理模式，你才能真正设计好一个 Agent 的行为逻辑。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一推理模式agent-的思考方式"&gt;一、推理模式：Agent 的&amp;quot;思考方式&amp;quot;
&lt;/h2&gt;&lt;p&gt;LLM 面对复杂任务时，&amp;ldquo;一口气&amp;quot;预测答案容易出错。推理模式就是给 LLM 一个&amp;quot;思考框架&amp;rdquo;，让它分步骤、有结构地解决问题。&lt;/p&gt;
&lt;p&gt;从最基础到最复杂，主要有三种推理模式：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;本质&lt;/th&gt;
&lt;th&gt;是否可观察推理过程&lt;/th&gt;
&lt;th&gt;复杂度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Direct（直接回答）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;一步到位给出答案&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CoT（思维链）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;先写出推理过程，再给答案&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ReAct（推理+行动）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;交替推理和工具调用，形成循环&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="二cotchain-of-thought-思维链"&gt;二、CoT：Chain-of-Thought 思维链
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;核心思想&lt;/strong&gt;：让 LLM 不要直接给答案，而是先把中间推理步骤写出来。&lt;/p&gt;
&lt;h3 id="为什么-cot-有效"&gt;为什么 CoT 有效？
&lt;/h3&gt;&lt;p&gt;数学问题是最好的案例：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不用 CoT&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;问题：小明有 5 个苹果，小红比他多 3 个，小红有几个？
答案：8（对了）&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;用 CoT&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;问题：小明有 5 个苹果，小红比他多 3 个，小红有几个？
推理：小明的数量 = 5，小红比小明多 3 个，所以小红的数量 = 5 + 3 = 8。
答案：8（更可靠）&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;虽然加法例子不明显，但换到多步推理时：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;问题：鸡兔同笼，头共 35 个，脚共 94 只，鸡和兔各多少？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;不用 CoT 时，模型可能直接猜一个数。用 CoT 时，模型会一步步：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;设鸡 x 只，兔 y 只&lt;/li&gt;
&lt;li&gt;x + y = 35&lt;/li&gt;
&lt;li&gt;2x + 4y = 94&lt;/li&gt;
&lt;li&gt;解方程组&amp;hellip;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="触发-cot-的方法"&gt;触发 CoT 的方法
&lt;/h3&gt;&lt;p&gt;最简单的触发是在 prompt 里加一句：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Let&amp;rsquo;s think step by step.&amp;quot;（让我们一步步来）&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;进阶方法是给几个 Few-shot 示例，每个示例都展示完整的推理过程：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;请按照以下格式回答：[推理过程] → [最终答案]&amp;rdquo;&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id="三reactreason--act-推理行动"&gt;三、ReAct：Reason + Act 推理+行动
&lt;/h2&gt;&lt;p&gt;ReAct 是 Agent 中最核心的推理模式，来源论文：《ReAct: Synergizing Reasoning and Acting in Language Models》(2022)。&lt;/p&gt;
&lt;h3 id="react-的核心循环"&gt;ReAct 的核心循环
&lt;/h3&gt;&lt;p&gt;LLM 在执行中的每一步，都必须输出一个固定格式的三元组：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Thought: [对当前状态的推理思考]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Action: [决定调用哪个工具，带什么参数]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Observation: [工具返回的结果]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;循环执行，直到任务完成：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户：北京今天天气怎么样适合穿什么？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Thought: 用户想知道北京的天气和穿衣建议。我需要先查天气。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Action: weather_query(city=&amp;#34;北京&amp;#34;, date=&amp;#34;today&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Observation: {temperature: 25, condition: &amp;#34;多云&amp;#34;, wind: &amp;#34;2级&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Thought: 北京今天25度多云，适宜穿着。可以建议轻薄长袖或短袖加薄外套。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Action: user_answer(&amp;#34;北京今天多云，气温25度，风力较小。建议穿短袖配薄外套，或轻薄长袖。&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="react-为什么是最主流的-agent-模式"&gt;ReAct 为什么是最主流的 Agent 模式？
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;推理过程透明&lt;/strong&gt;：每一步都在 &amp;ldquo;Thought&amp;rdquo; 里写明白了为什么做这个决定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误可诊断&lt;/strong&gt;：如果结果错了，可以回看 &amp;ldquo;Thought&amp;rdquo; 找到决策缺陷&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接口标准化&lt;/strong&gt;：代码只需要解析 Thought/Action/Observation 三种标签&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可扩展性强&lt;/strong&gt;：新工具加进来，不需要改代码逻辑，只需要加 schema&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="react-的实现要点"&gt;ReAct 的实现要点
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;System Prompt 的设计&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;你是&lt;/span&gt; &lt;span class="n"&gt;ReAct&lt;/span&gt; &lt;span class="err"&gt;智能体。遵循以下工作流程：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="mf"&gt;1.&lt;/span&gt; &lt;span class="err"&gt;分析当前任务状态&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="mf"&gt;2.&lt;/span&gt; &lt;span class="err"&gt;在&lt;/span&gt; &lt;span class="n"&gt;Thought&lt;/span&gt; &lt;span class="err"&gt;中写出你的推理过程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="mf"&gt;3.&lt;/span&gt; &lt;span class="err"&gt;如果有需要调用的工具，在&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="err"&gt;中输出工具调用&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="mf"&gt;4.&lt;/span&gt; &lt;span class="err"&gt;等待&lt;/span&gt; &lt;span class="n"&gt;Observation&lt;/span&gt; &lt;span class="err"&gt;结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="mf"&gt;5.&lt;/span&gt; &lt;span class="err"&gt;重复步骤&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="err"&gt;直到任务完成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="mf"&gt;6.&lt;/span&gt; &lt;span class="err"&gt;最后直接在&lt;/span&gt; &lt;span class="n"&gt;Answer&lt;/span&gt; &lt;span class="err"&gt;中给出最终答案&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;格式要求：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Thought&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;你的思考&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tool&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tool_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;params&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Observation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;工具结果（由系统自动填充）&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Answer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;最终答案（仅在任务完成时输出）&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;重要：如果没有需要调用的工具，直接输出&lt;/span&gt; &lt;span class="n"&gt;Answer&lt;/span&gt;&lt;span class="err"&gt;。不要编造&lt;/span&gt; &lt;span class="n"&gt;Observation&lt;/span&gt;&lt;span class="err"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="四plan-and-execute先规划再执行"&gt;四、Plan-and-Execute：先规划再执行
&lt;/h2&gt;&lt;p&gt;ReAct 是&amp;quot;走一步看一步&amp;quot;的灵活模式，Plan-and-Execute 是&amp;quot;先想好全盘再动手&amp;rdquo;。&lt;/p&gt;
&lt;h3 id="流程对比"&gt;流程对比
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;ReAct&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户目标 → LLM 思考 → 调工具 → 看到结果 → LLM 再思考 → 调工具...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;（每一步都根据上一步结果动态决定）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Plan-and-Execute&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户目标 → LLM 生成完整计划（步骤1-5） → 按顺序执行每一步 → 汇总输出
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="各自优劣"&gt;各自优劣
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;ReAct&lt;/th&gt;
&lt;th&gt;Plan-and-Execute&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;适用任务&lt;/td&gt;
&lt;td&gt;信息不确定、需要探索的&lt;/td&gt;
&lt;td&gt;流程清晰、确定性高的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;灵活性&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可控性&lt;/td&gt;
&lt;td&gt;低（可能跑偏）&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;token 消耗&lt;/td&gt;
&lt;td&gt;多（每步都推理）&lt;/td&gt;
&lt;td&gt;少（一次规划）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;调试难度&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="实践中怎么选"&gt;实践中怎么选？
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;知识问答类&lt;/strong&gt;（搜索→整合→回答）：ReAct，过程中信息不确定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据分析类&lt;/strong&gt;（读数据→分析→出报告）：Plan-and-Execute，流程相对固定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;复杂长流程&lt;/strong&gt;：混合模式，大方向 plan → 每步内部用 ReAct 灵活处理&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="五reflection自我检查与修正"&gt;五、Reflection：自我检查与修正
&lt;/h2&gt;&lt;p&gt;Reflection 不是独立的流程，而是给 ReAct 或 Plan-and-Execute 加的&lt;strong&gt;质量检查 buff&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="思路"&gt;思路
&lt;/h3&gt;&lt;p&gt;在完成输出后，让 LLM 自己审视一下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Thought: 我已经完成了任务，给出了回答。让我检查一下：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. 答案是否完整覆盖了用户的所有问题？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. 有没有遗漏的关键信息？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. 推理过程是否有漏洞？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;反思：我注意到用户的问题里还提到了&amp;#34;预算&amp;#34;，但我的回答里没有涉及费用评估...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;修正：补充预算分析...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="适用场景"&gt;适用场景
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;高风险任务（如医疗建议、法律分析）&lt;/li&gt;
&lt;li&gt;输出后用户可以清晰判断对错的任务&lt;/li&gt;
&lt;li&gt;有客观评估标准的任务&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="代价"&gt;代价
&lt;/h3&gt;&lt;p&gt;Self-reflection 多跑一次 LLM，&lt;strong&gt;token 成本和延迟都会增加&lt;/strong&gt;。这是工程上的必要取舍。&lt;/p&gt;
&lt;h2 id="六三种范式的核心区别"&gt;六、三种范式的核心区别
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;范式&lt;/th&gt;
&lt;th&gt;解决什么问题&lt;/th&gt;
&lt;th&gt;决策时机&lt;/th&gt;
&lt;th&gt;工程复杂度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ReAct&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;单步灵活性，动态调整&lt;/td&gt;
&lt;td&gt;每一步实时决策&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Plan-and-Execute&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;长任务不跑偏&lt;/td&gt;
&lt;td&gt;开始前一次性规划&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reflection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;输出质量不够好&lt;/td&gt;
&lt;td&gt;完成后检查修正&lt;/td&gt;
&lt;td&gt;中（作为模块叠加）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="七本章小结"&gt;七、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;推理模式是给 LLM 一个&amp;quot;思考框架&amp;quot;&lt;/li&gt;
&lt;li&gt;CoT 教 LLM&amp;quot;先想后答&amp;quot;，适合数学题、推理解释&lt;/li&gt;
&lt;li&gt;ReAct 教 LLM&amp;quot;边想边做&amp;quot;，是 Agent 最主流的推理范式&lt;/li&gt;
&lt;li&gt;Plan-and-Execute 教 LLM&amp;quot;先想全再做&amp;quot;，适合确定性流程&lt;/li&gt;
&lt;li&gt;Reflection 是&amp;quot;做完检查&amp;quot;的质量保障机制，可与前两者叠加&lt;/li&gt;
&lt;li&gt;选型标准：任务复杂度、流程确定性、输出质量要求&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;一个客服 Agent 处理退款申请，适合用哪种推理模式？为什么？&lt;/li&gt;
&lt;li&gt;如果你发现 ReAct 模式下 Agent 经常陷入循环（思考 → 调工具 → 思考 → 调同一个工具），你会从哪些角度排查和解决？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第11章：Agent 核心架构拆解——四个缺一不可的组件</title><link>https://blog.irudder.me/ai/knowledge-series/11-Agent-Core-Architecture-Explained.html</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/11-Agent-Core-Architecture-Explained.html</guid><description>&lt;h1 id="第11章agent-核心架构拆解四个缺一不可的组件"&gt;第11章：Agent 核心架构拆解——四个缺一不可的组件
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：本章深入 Agent 的内部结构。如果你准备亲手实现一个 Agent，这就是你要看的「系统说明书&amp;quot;。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一agent架构全景四个核心组件"&gt;一、Agent架构全景：四个核心组件
&lt;/h2&gt;&lt;p&gt;一个完整的 Agent 系统由以下四个核心组件构成，任何一个掉链子，系统都跑不好：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 用户输入 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────┬───────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 1. LLM 核心 ←所有决策的中枢 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ↓ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 2. 规划模块 ←把目标拆成步骤 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ↓ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 3. 工具系统 ←实际执行的能力 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ↓ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ 4. 记忆系统 ←持续维护的状态 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="二组件1llm-核心"&gt;二、组件1：LLM 核心
&lt;/h2&gt;&lt;p&gt;LLM 是整个 Agent 的「大脑」。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;所有输入（用户指令、工具返回结果、记忆内容）最终都经过 LLM 来理解和决策&lt;/li&gt;
&lt;li&gt;LLM 负责判断：&lt;strong&gt;下一步该做什么？继续思考？调用工具？还是输出最终答案？&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="system-prompt-的关键作用"&gt;System Prompt 的关键作用
&lt;/h3&gt;&lt;p&gt;System Prompt 就是给 Agent 的「岗位说明书」，定义了：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;你是一个专业的数据分析助手。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;你的任务是帮助用户分析数据并生成报告。
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;你可以使用的工具：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. analyze_csv：读取 CSV 文件并做基础统计分析
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. generate_chart：根据数据生成可视化图表
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. web_search：搜索最新行业信息
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. write_report：生成结构化报告
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;你的工作流程：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. 先理解用户的数据分析目标
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. 使用 analyze_csv 了解数据概况
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. 根据数据特征选择分析方向
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. 使用 generate_chart 生成必要的可视化
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5. 最后使用 write_report 生成完整报告
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;System Prompt 写得好不好，直接决定 Agent 的行为模式&lt;/strong&gt;。它是工程质量最不可控的变量之一。&lt;/p&gt;
&lt;h2 id="三组件2规划模块planning"&gt;三、组件2：规划模块（Planning）
&lt;/h2&gt;&lt;p&gt;规划模块解决的是：&lt;strong&gt;怎么把一个大目标拆成可执行的步骤？&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="为什么需要规划"&gt;为什么需要规划？
&lt;/h3&gt;&lt;p&gt;想象你让 Agent 完成：&amp;ldquo;帮我分析我们公司 Q2 的销售数据，找出增长最快的产品线，并给出下季度的推广建议。&amp;rdquo;&lt;/p&gt;
&lt;p&gt;这个任务拆下去至少包含：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;加载并描述销售数据（analyze_csv）&lt;/li&gt;
&lt;li&gt;按产品线分组计算增长率&lt;/li&gt;
&lt;li&gt;找出增长最快的产品线&lt;/li&gt;
&lt;li&gt;搜索该产品的市场信息&lt;/li&gt;
&lt;li&gt;结合数据和市场信息生成建议&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;没有规划模块，LLM 一次调用只能做一件事，可能会重复、遗漏或顺序错乱。&lt;/p&gt;
&lt;h3 id="两种规划策略"&gt;两种规划策略
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;策略&lt;/th&gt;
&lt;th&gt;实现方式&lt;/th&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;静态规划&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;预先定义步骤序列（工作流）&lt;/td&gt;
&lt;td&gt;确定性高，灵活性差&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;动态规划&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;让 LLM 每一步自己决定方向和工具&lt;/td&gt;
&lt;td&gt;灵活性强，可控性差&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;混合规划&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;大方向固定，具体操作让 LLM 决定&lt;/td&gt;
&lt;td&gt;推荐方案&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;动态规划示例（ReAct 模式）：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;步骤1：Thought &amp;#34;我需要先了解数据概况&amp;#34; → Action: analyze_csv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;步骤2：Thought &amp;#34;数据里有哪些列？产品分类是什么？&amp;#34; → 根据结果继续
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;步骤3：Thought &amp;#34;让我按产品线计算增长率&amp;#34; → Action: analyze_csv + 参数
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="四组件3工具系统tool-system"&gt;四、组件3：工具系统（Tool System）
&lt;/h2&gt;&lt;p&gt;工具系统是 Agent 与外部世界交互的「四肢」。&lt;/p&gt;
&lt;p&gt;工具不是越多越好。过多的工具会让 LLM 的选择困难增加（context 装不下、选错概率上升）。&lt;/p&gt;
&lt;h3 id="工具定义的关键要素"&gt;工具定义的关键要素
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;web_search&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;当需要获取某个领域的最新信息、验证某个事实、或者了解某个概念时使用。注意：不要用来查询本地数据库的内容&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;parameters&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;搜索关键词，建议3-5个关键词，不要太长&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;description 是核心门槛&lt;/strong&gt;——模型基于 description 决定用不用这个工具。写好 description 的技巧：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;明确什么场景用&lt;/li&gt;
&lt;li&gt;明确什么场景&lt;strong&gt;不用&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;给出使用示例&lt;/li&gt;
&lt;li&gt;说明参数要求&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="工具的返回值设计"&gt;工具的返回值设计
&lt;/h3&gt;&lt;p&gt;工具返回的结果也需要精心格式化：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;工具调用的结果应该：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. 结构化（JSON 或 Markdown 表格）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. 包含执行状态（成功/失败）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. 失败时包含错误信息和可能的修正建议
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. 避免过长的原始输出，必要时做摘要
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="五组件4记忆系统memory"&gt;五、组件4：记忆系统（Memory）
&lt;/h2&gt;&lt;p&gt;记忆系统解决的是：&lt;strong&gt;Agent 怎么记得之前做过什么？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;记忆分四个层次：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;层次&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;th&gt;存储位置&lt;/th&gt;
&lt;th&gt;生命周期&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;感知记忆&lt;/td&gt;
&lt;td&gt;当前输入的原始内容&lt;/td&gt;
&lt;td&gt;内存&lt;/td&gt;
&lt;td&gt;即时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;短期记忆&lt;/td&gt;
&lt;td&gt;当前对话/任务的历史&lt;/td&gt;
&lt;td&gt;Context window&lt;/td&gt;
&lt;td&gt;当前任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;长期记忆&lt;/td&gt;
&lt;td&gt;跨会话的知识和经验&lt;/td&gt;
&lt;td&gt;向量数据库/结构化存储&lt;/td&gt;
&lt;td&gt;持续&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;实体记忆&lt;/td&gt;
&lt;td&gt;提取的结构化事实&lt;/td&gt;
&lt;td&gt;图数据库/KV 存储&lt;/td&gt;
&lt;td&gt;持续&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="为什么记忆系统这么重要"&gt;为什么记忆系统这么重要？
&lt;/h3&gt;&lt;p&gt;没有记忆的 Agent：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你在上一步确认了技术方案，下一步它就不记得了&lt;/li&gt;
&lt;li&gt;它不知道你的偏好（代码风格、输出格式）&lt;/li&gt;
&lt;li&gt;它无法在多个任务之间保持连贯性&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有记忆的 Agent：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;记住你们的约定和达成的共识 → 持续协作质量提升&lt;/li&gt;
&lt;li&gt;记住任务的历史决策 → 避免重复讨论、减少沟通成本&lt;/li&gt;
&lt;li&gt;跨任务积累对你的了解 → 越来越懂你&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="六四个组件的协同"&gt;六、四个组件的协同
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户：分析 sales.csv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LLM（理解目标）→ 规划模块：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;目标：分析销售数据 → 步骤：1.读数据 2.做统计 3.出报告&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LLM（步骤1）→ &amp;#34;调 analyze_csv(sales.csv)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 工具系统执行 → 返回数据描述
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LLM（步骤2）→ 看到数据是时间序列 → &amp;#34;调 analyze_csv + 增长分析参数&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 工具系统执行 → 返回分析结果
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;记忆系统：记录当前进度、中间结果、用户偏好
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LLM（步骤3）→ &amp;#34;数据够用，生成报告&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 调 write_report → 输出最终答案给用户
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="七本章小结"&gt;七、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Agent 四大组件：LLM（大脑）、规划（怎么拆任务）、工具（怎么做）、记忆（记得什么）&lt;/li&gt;
&lt;li&gt;LLM 的 System Prompt 定义了 Agent 的&amp;quot;人格&amp;quot;和&amp;quot;行为边界&amp;quot;&lt;/li&gt;
&lt;li&gt;规划模块是连接目标和执行的桥梁，静态保守、动态灵活&lt;/li&gt;
&lt;li&gt;工具系统的 description 质量直接决定调用准确率&lt;/li&gt;
&lt;li&gt;记忆系统让 Agent 有&amp;quot;持续感&amp;quot;，不是每次都从零开始&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;如果你设计一个 Agent，工具数量限制在 5 个以内，你怎么选择？优先级怎么排？&lt;/li&gt;
&lt;li&gt;短期记忆（存在 context 里）会随着对话变长而被截断。长任务中如何设计记忆的&amp;quot;生命值&amp;quot;决策？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第10章：从 Prompt 到 Agent——AI 能力跃迁的分水岭</title><link>https://blog.irudder.me/ai/knowledge-series/10-From-Prompt-to-Agent.html</link><pubDate>Tue, 16 Jun 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/10-From-Prompt-to-Agent.html</guid><description>&lt;h1 id="第10章从-prompt-到-agentai-能力跃迁的分水岭"&gt;第10章：从 Prompt 到 Agent——AI 能力跃迁的分水岭
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：本章是 Agent 模块的开篇。建议先看第1-5章建立 LLM 和工具调用的基础认知，再进入 Agent 的学习。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一为什么说-prompt-和-agent-之间有一道鸿沟"&gt;一、为什么说 Prompt 和 Agent 之间有一道鸿沟？
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Prompt 时代&lt;/strong&gt;：你给模型一个指令，模型给你一个回答。对话结束。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agent 时代&lt;/strong&gt;：你给模型一个目标，模型决定需要什么信息，去搜索、执行、验证，最终给你一个完整的解决方案。&lt;/p&gt;
&lt;p&gt;这个分水岭就是：&lt;strong&gt;自主性（Autonomy）&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;能力&lt;/th&gt;
&lt;th&gt;Prompt&lt;/th&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;理解任务&lt;/td&gt;
&lt;td&gt;被动接收指令&lt;/td&gt;
&lt;td&gt;主动解析目标&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;工具调用&lt;/td&gt;
&lt;td&gt;没有&lt;/td&gt;
&lt;td&gt;自主决定用什么工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;多步执行&lt;/td&gt;
&lt;td&gt;没有&lt;/td&gt;
&lt;td&gt;可执行多步操作链&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;状态保持&lt;/td&gt;
&lt;td&gt;无（每次独立）&lt;/td&gt;
&lt;td&gt;有（记忆系统）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;结果验证&lt;/td&gt;
&lt;td&gt;没有&lt;/td&gt;
&lt;td&gt;自检查/自修正&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;闭环能力&lt;/td&gt;
&lt;td&gt;开环（输出即结束）&lt;/td&gt;
&lt;td&gt;闭环（输出→行动→反馈→再决策）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="二理解-agent不是加了工具的-llm"&gt;二、理解 Agent：不是「加了工具的 LLM」
&lt;/h2&gt;&lt;p&gt;最常被误解的概念：Agent 不是&amp;quot;给 LLM 加了几个 Function Calling&amp;quot;。&lt;/p&gt;
&lt;p&gt;真正的 Agent 有三个核心特征：&lt;/p&gt;
&lt;h3 id="1-自主决策"&gt;1. 自主决策
&lt;/h3&gt;&lt;p&gt;模型自己判断「下一步该做什么」，不是人类在每个节点发指令。&lt;/p&gt;
&lt;h3 id="2-行动-感知-调整闭环"&gt;2. 行动-感知-调整闭环
&lt;/h3&gt;&lt;p&gt;模型执行一个行动（如搜索），收到结果，然后根据结果调整下一步的计划。&lt;/p&gt;
&lt;h3 id="3-状态管理"&gt;3. 状态管理
&lt;/h3&gt;&lt;p&gt;在多步执行过程中，模型知道自己之前做了什么、当前进展到哪一步。这不是简单的对话历史，而是&lt;strong&gt;结构化的任务状态&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="三agent-与三个易混淆概念的区别"&gt;三、Agent 与三个易混淆概念的区别
&lt;/h2&gt;&lt;h3 id="tools最小的能力积木"&gt;Tools：最小的能力积木
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;一个封装好的可调用函数&lt;/li&gt;
&lt;li&gt;只负责执行，自己不做任何决策&lt;/li&gt;
&lt;li&gt;如：搜索 API、发邮件 API、查询数据库&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="agent完整的决策系统"&gt;Agent：完整的决策系统
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;内部用 LLM 做大脑&lt;/li&gt;
&lt;li&gt;自己判断「要不要调工具」「调哪个工具」「什么时候结束&amp;quot;&lt;/li&gt;
&lt;li&gt;是主动的执行者&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="workflow确定性流程编排"&gt;Workflow：确定性流程编排
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;开发者事先写好所有节点和流转逻辑&lt;/li&gt;
&lt;li&gt;什么时候调什么工具、走什么分支，都是代码写死的&lt;/li&gt;
&lt;li&gt;LLM 只负责某个节点的执行，不负责流程决策&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;核心区分维度：谁来做&amp;quot;下一步该干什么&amp;quot;这个决策？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tools：不做决策，只执行&lt;/li&gt;
&lt;li&gt;Agent：自己决策&lt;/li&gt;
&lt;li&gt;Workflow：开发者替所有节点决策&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="四为什么说-agent-是-llm-进化的必然"&gt;四、为什么说 Agent 是 LLM 进化的必然？
&lt;/h2&gt;&lt;p&gt;你问 LLM：&amp;ldquo;帮我规划一个去三亚旅游的7天行程。&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果没有工具&lt;/strong&gt;：LLM 只能根据训练数据给出建议，信息可能已经过时，也无法查实时机票和酒店价格。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;有了工具但没 Agent&lt;/strong&gt;：你可以手动把多个工具的调用写好，串成一个流程。但问题是：不同的输入可能需要不同的流程。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;有了 Agent&lt;/strong&gt;：把目标交给它，它自己决定要不要查天气、查酒店、查景点，把所有信息汇总后再出方案，而且每个步骤都会有实时数据。&lt;/p&gt;
&lt;p&gt;Agent 让 LLM 从一个「有知识的回答者」变成了一个「能行动的智能体」。&lt;/p&gt;
&lt;h2 id="五agent-基础工作模式"&gt;五、Agent 基础工作模式
&lt;/h2&gt;&lt;p&gt;最基础的 Agent 循环：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌───────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 用户输入目标 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────────┬─────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ LLM 分析目标，判断需要什么信息 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────────────────┬───────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ LLM 决定调用哪个工具，输出参数 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────────────────┬───────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 代码执行工具，获取结果 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────────────────┬───────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ 结果反馈给 LLM │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────────────────┬───────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ LLM 判断是否完成任务： │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ → 未完成，继续循环 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ → 完成，输出最终答案 │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个循环跑几次（迭代次数取决于任务复杂度），最后输出综合答案。&lt;/p&gt;
&lt;h2 id="六从-prompt-到-agent-的思维转变"&gt;六、从 Prompt 到 Agent 的思维转变
&lt;/h2&gt;&lt;p&gt;作为开发者，你需要从「写 prompt 让模型回答」转变为「设计一个系统让模型自主决策」。&lt;/p&gt;
&lt;p&gt;核心设计要素：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;System Prompt&lt;/strong&gt;：给模型设定 &amp;ldquo;你是谁、你能做什么、你的工具是什么&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool Schema&lt;/strong&gt;：精确定义工具的使用方式&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory 设计&lt;/strong&gt;：管理中间状态和历史 context&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;终止条件&lt;/strong&gt;：什么时候算完成了？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误处理&lt;/strong&gt;：工具调用失败怎么办？模型决策跑偏怎么办？&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="七本章小结"&gt;七、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Agent 的质变在于&amp;quot;自主决策&amp;quot;和&amp;quot;行动-感知-调整闭环&amp;quot;&lt;/li&gt;
&lt;li&gt;Tools、Agent、Workflow 是三层不同粒度的概念，不是替代关系&lt;/li&gt;
&lt;li&gt;Agent 让 LLM 从&amp;quot;回答者&amp;quot;升级为&amp;quot;行动者&amp;quot;&lt;/li&gt;
&lt;li&gt;开发 Agent 需要设计思维转变：从&amp;quot;写 prompt&amp;quot;到&amp;quot;设计自主系统&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;一个天气预报查询任务，用纯 prompt、用 workflow、用 agent，三种方案各有什么优劣？&lt;/li&gt;
&lt;li&gt;Agent 的&amp;quot;自主决策&amp;quot;在哪些场景下是优势，在哪些场景下是风险？如何平衡自主性和可控性？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第9章：RAG 检索优化全攻略——从召回率到答案质量</title><link>https://blog.irudder.me/ai/knowledge-series/09-RAG-Retrieval-Optimization-Guide.html</link><pubDate>Mon, 15 Jun 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/09-RAG-Retrieval-Optimization-Guide.html</guid><description>&lt;h1 id="第9章rag-检索优化全攻略从召回率到答案质量"&gt;第9章：RAG 检索优化全攻略——从召回率到答案质量
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：检索是 RAG 的命脉，召回的内容质量决定了 LLM 回答的天花板。本章系统讲解检索优化的四维框架。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一为什么要系统优化检索"&gt;一、为什么要系统优化检索？
&lt;/h2&gt;&lt;p&gt;先看三个现实问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用户问&amp;quot;退款政策&amp;quot;，召回的第一步是&amp;quot;配送说明&amp;quot;，第二步才是&amp;quot;退款政策&amp;quot;——漏召回&lt;/li&gt;
&lt;li&gt;用户问&amp;quot;这个功能怎么用？&amp;quot;，召回的 10 个 chunk 里有 3 个完全无关——召回噪音大&lt;/li&gt;
&lt;li&gt;用户问了一个涉及两个不同知识点的复合问题，检索只找到了其中一个——覆盖不全&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这三个问题对应的分别是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;召回精度的优化&lt;/li&gt;
&lt;li&gt;召回噪音的优化&lt;/li&gt;
&lt;li&gt;多路召回的优化&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="二四层检索优化框架"&gt;二、四层检索优化框架
&lt;/h2&gt;&lt;h3 id="第一层索引层知识怎么存"&gt;第一层：索引层——知识怎么存
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;切割策略优化&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第7章讲过的四种策略按需选择和组合&lt;/li&gt;
&lt;li&gt;父子结构不过分零碎也不过分庞大&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;metadata 索引&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;为每个 chunk 打上分类标签、文档类型、版本号、创建时间&lt;/li&gt;
&lt;li&gt;检索时做前置过滤，缩小搜索范围&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;向量索引参数调优&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HNSW 的 ef_construction：构建时越精细，搜索越准，但构建越慢&lt;/li&gt;
&lt;li&gt;HNSW 的 ef_search：搜索时额外探索更多候选，提高召回率但增加延迟&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="第二层查询层问题怎么转换"&gt;第二层：查询层——问题怎么转换
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Query Rewrite 四大方法&lt;/strong&gt;（详见第6章总结）：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;核心思想&lt;/th&gt;
&lt;th&gt;解决的问题&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;直接改写&lt;/td&gt;
&lt;td&gt;口语 → 书面语&lt;/td&gt;
&lt;td&gt;用户提问随意&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查询扩展&lt;/td&gt;
&lt;td&gt;加相关关键词&lt;/td&gt;
&lt;td&gt;术语不匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HyDE&lt;/td&gt;
&lt;td&gt;LLM 假设答案 → 用答案向量检索&lt;/td&gt;
&lt;td&gt;用户问题表述匮乏&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Step-back&lt;/td&gt;
&lt;td&gt;抽象具体问题&lt;/td&gt;
&lt;td&gt;需要更广泛背景&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;应用场景举例&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户问&amp;quot;这东西坏了咋整&amp;quot;→ 直接改写成&amp;quot;产品故障排查指南&amp;quot;&lt;/li&gt;
&lt;li&gt;用户问&amp;quot;张三是谁&amp;quot;→ 扩展&amp;quot;张三 | 人物 | 简介 | 生平&amp;quot;&lt;/li&gt;
&lt;li&gt;用户只有一个缩写词&amp;quot;OKR&amp;quot;→ Step-back 到&amp;quot;目标管理体系&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="第三层召回层从哪些路径找"&gt;第三层：召回层——从哪些路径找
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;多路召回&lt;/strong&gt;：不走单一检索路径，而是从多个角度同时找，然后把结果合并：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─ 向量检索（语义匹配） → Top-K1 结果
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ BM25/全文检索（关键词匹配） → Top-K2 结果
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ 结构化查询（metadata过滤 + 精确匹配） → Top-K3 结果
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─ 混合融合 → 去重 → 合并排序 → 进入 Rerank
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;每种召回方法有不同的优势&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;向量检索&lt;/strong&gt;：语义相近但用词不同的内容&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BM25&lt;/strong&gt;：精确的关键词匹配、术语命中&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structured Query&lt;/strong&gt;：条件查找（某版本、某产品的文档）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;融合策略&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;加权融合&lt;/strong&gt;：weight_vector × score_vector + weight_bm25 × score_bm25&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RRF（Reciprocal Rank Fusion）&lt;/strong&gt;：不关心绝对分数，只关心排名位置&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="第四层重排序层哪些给-llm"&gt;第四层：重排序层——哪些给 LLM
&lt;/h3&gt;&lt;p&gt;粗招召回的结果数量通常远超过 LLM context 能容纳的。Rerank 的作用：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;用更精确的模型重新打分，选最相关的 Top-N 传给 LLM&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;常见 Rerank 方案&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Cross-Encoder Reranker&lt;/strong&gt;：问题和每个 chunk 拼接一起送进模型，输出一个相关性分数。比双塔（bi-encoder）更准但计算更慢&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM-as-Judge&lt;/strong&gt;：让 LLM 对每个召回 chunk 打分（慢但效果最好，适合少量结果）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;规则过滤&lt;/strong&gt;：按 metadata 排除明显不相关的&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="三系统性优化流程"&gt;三、系统性优化流程
&lt;/h2&gt;&lt;p&gt;不要东一榔头西一棒槌，按以下流程来：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;步骤1：建立评估基准
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 标注 50-100 组&amp;#34;问题/期望答案&amp;#34;，称为 golden set
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;步骤2：跑基线
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 用最简单的 chunking + 默认模型 + 向量检索，测召回率和答案质量
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;步骤3：逐层优化
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 先看召回层：调整 chunking、换 Embedding 模型、加多路召回
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 再看查询层：加 Query Rewrite，看是否能召回原本漏掉的内容
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 最后看重排序层：加 Reranker，提高精度、降低噪音
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;步骤4：回归验证
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 每次改动后跑 full golden set，确保没有 regression
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="四常见检索-bad-case-速查表"&gt;四、常见检索 bad case 速查表
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;现象&lt;/th&gt;
&lt;th&gt;根因&lt;/th&gt;
&lt;th&gt;解法&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;问题措辞不同就检索不到&lt;/td&gt;
&lt;td&gt;Embedding 语义映射不够&lt;/td&gt;
&lt;td&gt;换模型 / 加 Query Rewrite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;专有名词搜不到&lt;/td&gt;
&lt;td&gt;语义匹配 + 精确匹配不足&lt;/td&gt;
&lt;td&gt;加 BM25 / 结构化索引&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;召回很多无关内容&lt;/td&gt;
&lt;td&gt;粗排粒度太粗&lt;/td&gt;
&lt;td&gt;加 Reranker / 缩小 Top-K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;需要跨文档关联才能回答&lt;/td&gt;
&lt;td&gt;单路召回覆盖不全&lt;/td&gt;
&lt;td&gt;多路召回 + 多跳检索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;召回内容正确但太碎片化&lt;/td&gt;
&lt;td&gt;Chunk 太小&lt;/td&gt;
&lt;td&gt;父子结构 / 增大 chunk&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="五本章小结"&gt;五、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;检索优化的目标：不漏（召回率）、不杂（精确度）、够用（覆盖度）&lt;/li&gt;
&lt;li&gt;四层框架：索引层 → 查询层 → 召回层 → 重排序层&lt;/li&gt;
&lt;li&gt;黄金法则：先建评估基准（golden set），再逐层优化，每次改动都跑回归&lt;/li&gt;
&lt;li&gt;RAG 系统的上限在检索层，搜索做得越好，LLM 回答的天花板越高&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;多路召回中，向量检索和 BM25 的分数范围不同，直接加权融合可能不公平。你除了 RRF 之外还有什么融合策略？&lt;/li&gt;
&lt;li&gt;如果你的 golden set 只有 20 条，怎么防止过拟合评估集？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第8章：Embedding 与向量数据库——RAG 的技术底座</title><link>https://blog.irudder.me/ai/knowledge-series/08-Embedding-and-Vector-Database-Selection.html</link><pubDate>Sat, 13 Jun 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/08-Embedding-and-Vector-Database-Selection.html</guid><description>&lt;h1 id="第8章embedding-与向量数据库rag-的技术底座"&gt;第8章：Embedding 与向量数据库——RAG 的技术底座
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：本章讲 RAG 的&amp;quot;底层基础设施&amp;quot;。选对了 Embedding 模型和向量数据库，后面的优化事半功倍；选错了，上层做再多也救不回来。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一embedding-到底做了一件什么事"&gt;一、Embedding 到底做了一件什么事？
&lt;/h2&gt;&lt;p&gt;Embedding（嵌入）做的事情本质上只有一件：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;把一段文本，映射成一个固定长度的浮点数向量。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;比如把 &amp;ldquo;今天天气很好&amp;rdquo; 转成：[0.023, -0.145, 0.778, &amp;hellip;]，长度比如 768 或 1024。&lt;/p&gt;
&lt;p&gt;这个映射最关键的性质：&lt;strong&gt;语义相近的文本，向量在空间中距离相近&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;度量方式通常用&lt;strong&gt;余弦相似度&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cos(A, B) = (A·B) / (||A|| × ||B||)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;值接近 1 表示高度相似，接近 0 表示无关。&lt;/p&gt;
&lt;h2 id="二如何选择-embedding-模型"&gt;二、如何选择 Embedding 模型？
&lt;/h2&gt;&lt;h3 id="维度"&gt;维度
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;384 维&lt;/strong&gt;：轻量，存储省，适合简单场景&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;768-1024 维&lt;/strong&gt;：最常用，精度够用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4096+ 维&lt;/strong&gt;：高精度，适合专业检索&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="语言"&gt;语言
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;纯中文&lt;/strong&gt;：BGE 系列（推荐 v1.5 或 M3E 通用版）、智谱 embedding&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中英混合&lt;/strong&gt;：BGE 系列、GTE 系列&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多语言&lt;/strong&gt;：OpenAI text-embedding-3, E5 multilang, GTE multilang&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="评估方式"&gt;评估方式
&lt;/h3&gt;&lt;p&gt;千万不要只看 MTEB 排行榜！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在自己的数据上跑模拟测试&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;标注一组 &amp;ldquo;问题 | 期望答案文档&amp;rdquo; 的配对&lt;/li&gt;
&lt;li&gt;用候选 Embedding 模型向量化问题和文档&lt;/li&gt;
&lt;li&gt;计算 Top-K 召回率、NDCG&lt;/li&gt;
&lt;li&gt;选实际效果最好的，不要迷信榜单第一&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;关键指标&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hit@K&lt;/strong&gt;：正确结果在 Top-K 中的占比&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NDCG@K&lt;/strong&gt;：不仅看命没命中，还看命中位置的排名质量&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="三向量数据库为什么不是普通的字典"&gt;三、向量数据库：为什么不是普通的字典？
&lt;/h2&gt;&lt;p&gt;向量数据库和普通数据库的根本区别：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;普通数据库&lt;/th&gt;
&lt;th&gt;向量数据库&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;查询方式&lt;/td&gt;
&lt;td&gt;精确匹配 / 范围查询&lt;/td&gt;
&lt;td&gt;近似最近邻搜索（ANN）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;索引结构&lt;/td&gt;
&lt;td&gt;B+ Tree / 哈希&lt;/td&gt;
&lt;td&gt;HNSW / IVF / DiskANN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据维度&lt;/td&gt;
&lt;td&gt;低维（几十列）&lt;/td&gt;
&lt;td&gt;高维（几百到几千列）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;准确率&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;可接受的近似误差（99%+）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;速度目标&lt;/td&gt;
&lt;td&gt;毫秒级精确查询&lt;/td&gt;
&lt;td&gt;毫秒级近似搜索（百万级数据）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;在高维空间里，最近邻搜索的复杂度是 O(n)。百万级数据全量扫描太慢了，所以必须做近似搜索。&lt;/p&gt;
&lt;h3 id="索引算法简述"&gt;索引算法简述
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;算法&lt;/th&gt;
&lt;th&gt;核心思想&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HNSW&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;构建多层图结构，像跳表一样逐层搜索&lt;/td&gt;
&lt;td&gt;内存充足、追求最高召回率&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IVF-PQ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;先聚类分桶，粗过滤后精计算&lt;/td&gt;
&lt;td&gt;磁盘存储、数据量极大&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DiskANN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HNSW 的磁盘友好版本，压缩存入 SSD&lt;/td&gt;
&lt;td&gt;十亿级数据&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="四向量数据库选型矩阵"&gt;四、向量数据库选型矩阵
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;产品&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;适用规模&lt;/th&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chroma&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;开源嵌入式&lt;/td&gt;
&lt;td&gt;开发/小项目&lt;/td&gt;
&lt;td&gt;零配置上手，嵌入式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Qdrant&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;开源服务端&lt;/td&gt;
&lt;td&gt;中小规模生产&lt;/td&gt;
&lt;td&gt;Rust 高性能，API 简洁&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Milvus/Zilliz&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;开源 + 云&lt;/td&gt;
&lt;td&gt;大规模/超大规模&lt;/td&gt;
&lt;td&gt;云原生设计，字节/阿里在用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pinecone&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;全托管云&lt;/td&gt;
&lt;td&gt;不想运维&lt;/td&gt;
&lt;td&gt;成本稍高，API 极简&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;pgvector&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PostgreSQL 插件&lt;/td&gt;
&lt;td&gt;已有 PG 架构&lt;/td&gt;
&lt;td&gt;无需引入新组件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Elasticsearch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;搜索引擎&lt;/td&gt;
&lt;td&gt;ES 集群已有&lt;/td&gt;
&lt;td&gt;向量检索是后来补的，性能一般&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;选型建议&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本地开发/原型阶段：Chroma（零配置）&lt;/li&gt;
&lt;li&gt;生产中小规模：Qdrant / pgvector&lt;/li&gt;
&lt;li&gt;大规模/云上：Milvus / Pinecone&lt;/li&gt;
&lt;li&gt;已有搜索架构扩展：在现有系统（ES/MeiliSearch）外挂向量能力&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="五embedding--向量库的完整链路"&gt;五、Embedding + 向量库的完整链路
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;文档 → 切割 → Chunking → Embedding 模型 → 向量 [v1, v2, ...] → 向量数据库写入
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;问题 → Embedding 模型（同一个！） → 查询向量 q → 向量库 ANN 搜索 → Top-K 结果 → Rerank → LLM
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;关键注意&lt;/strong&gt;：离线存储和在线查询&lt;strong&gt;必须&lt;/strong&gt;用&lt;strong&gt;同一个 Embedding 模型&lt;/strong&gt;。不同模型映射的向量空间不同，交叉使用会导致检索完全失败。&lt;/p&gt;
&lt;h2 id="六生产环境中的高级话题"&gt;六、生产环境中的高级话题
&lt;/h2&gt;&lt;h3 id="1-动态更新"&gt;1. 动态更新
&lt;/h3&gt;&lt;p&gt;知识库内容更新了怎么办？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增量写入：新文档 chunk → embedding → 插入&lt;/li&gt;
&lt;li&gt;删除：按 metadata 标识清理过期 chunk&lt;/li&gt;
&lt;li&gt;替换：先删后插（需要事务或软删除策略）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-混合搜索"&gt;2. 混合搜索
&lt;/h3&gt;&lt;p&gt;纯向量检索有局限（比如精确匹配产品型号时）。混合搜索 = 向量语义搜索 + 关键词全文搜索，两种结果融合：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;最终得分 = α × 向量相似度 + β × BM25 分数
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="3-多模态-embedding"&gt;3. 多模态 Embedding
&lt;/h3&gt;&lt;p&gt;不仅有文本 embedding，还有图片 embedding、音频 embedding。同一语义空间内，&amp;ldquo;一段描述&amp;rdquo; 和 &amp;ldquo;一张图片&amp;rdquo; 可以互相检索。这就是多模态 RAG 的基础。&lt;/p&gt;
&lt;h2 id="七本章小结"&gt;七、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Embedding 是&amp;quot;语义压缩&amp;quot;，让文本变成数学可度量&lt;/li&gt;
&lt;li&gt;选模型：以&lt;strong&gt;自己业务数据上的召回测试结果&lt;/strong&gt;为准，不是排行榜&lt;/li&gt;
&lt;li&gt;向量库的核心是 ANN 近似搜索，不是精确匹配&lt;/li&gt;
&lt;li&gt;选型矩阵覆盖从开发到生产的全链路需求&lt;/li&gt;
&lt;li&gt;同一个模型贯穿离线和在线链路是基本原则&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;为什么在高维空间里，传统数据结构（B+树、哈希）对最近邻搜索失效？这和高维空间的几何特性有什么关系？&lt;/li&gt;
&lt;li&gt;你设计一个 RAG 系统时，会怎么安排 Embedding 模型更新的灰度策略（避免在线查询和离线存储用的模型版本不一致）？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第7章：文档切割——Chunking 的策略与最佳实践</title><link>https://blog.irudder.me/ai/knowledge-series/07-Chunking-Strategies-and-Best-Practices.html</link><pubDate>Fri, 12 Jun 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/07-Chunking-Strategies-and-Best-Practices.html</guid><description>&lt;h1 id="第7章文档切割chunking-的策略与最佳实践"&gt;第7章：文档切割——Chunking 的策略与最佳实践
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：本章是 RAG 的进阶篇。很多人以为 chunking 就是「切成 500 token」，但实际上它是影响检索质量最关键的工程决策之一。不好的 chunking 策略会让检索系统形同虚设——合适的内容检索不到，不合适的内容塞给 LLM，最终答案质量大打折扣。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id="一为什么-chunking-决定-rag-生死"&gt;一、为什么 chunking 决定 RAG 生死？
&lt;/h2&gt;&lt;p&gt;RAG 系统里有一个核心事实：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LLM 最终回答的质量，取决于你放进 prompt 里的参考资料质量。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;参考资料哪来的？从向量库里检索来的。
向量库里存的是 chunk，chunk 是切割出来的。&lt;/p&gt;
&lt;p&gt;如果 chunk 把一段重要信息中间切断了，或者把两段无关内容塞进了一个 chunk，检索出来的就是垃圾。垃圾进，垃圾出。你放再贵的 Embedding 模型、再牛的 LLM，都救不回一块切烂的 chunk。&lt;/p&gt;
&lt;h2 id="二chunking-的四大基础策略"&gt;二、Chunking 的四大基础策略
&lt;/h2&gt;&lt;h3 id="策略1固定大小--重叠fixed-size-with-overlap"&gt;策略1：固定大小 + 重叠（Fixed Size with Overlap）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 原文：今天天气很好，小明去公园散步。他在湖边看到一只白鹭...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |-------chunk1-------|--------chunk2-------|
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 今天天气很好，小明去 明去公园散步。他在湖边
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (size=12, overlap=4) 看到一只白鹭在水面上
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (size=12, overlap=4)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：通用文本，写起来最快，作为基线方案再用别的方法优化。
&lt;strong&gt;参数建议&lt;/strong&gt;：每 chunk 500-1000 token 是常见起点；重叠 10-20% 防止信息在切分处丢失。
&lt;strong&gt;问题&lt;/strong&gt;：机械切分会切断语义边界。一个句子被拦腰截断，LLM 收到 chunk 后理解困难。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：实现极其简单，不需要解析文档结构，可移植性好。几乎所有初级 RAG 教程都用这个方案。&lt;/p&gt;
&lt;h3 id="策略2按语义边界切割semantic-chunking"&gt;策略2：按语义边界切割（Semantic Chunking）
&lt;/h3&gt;&lt;p&gt;观察文档结构，在天然边界处切：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Markdown/HTML 的标题、段落&lt;/li&gt;
&lt;li&gt;文档的章节层次&lt;/li&gt;
&lt;li&gt;知识库的主题切换&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 【原文】
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; # 第一章 Java 基础
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第一节 变量和数据类型
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 变量是程序中...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第二节 控制流
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if 语句用于...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ### 切分点：标题边界
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; chunk1 = &amp;#34;第一节 变量和数据类型\n变量是程序中...&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; chunk2 = &amp;#34;第二节 控制流\nif 语句用于...&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：结构化的知识库、技术文档、产品手册。
&lt;strong&gt;优势&lt;/strong&gt;：语意完整，检索命中后 LLM 能有完整上下文。
&lt;strong&gt;挑战&lt;/strong&gt;：不同文档格式解析不一致，需要自定义切分逻辑。比如 PDF 就没有天然的分段标记，需要先解析出文本结构再决定切割点。&lt;/p&gt;
&lt;h3 id="策略3按代码逻辑切割"&gt;策略3：按代码逻辑切割
&lt;/h3&gt;&lt;p&gt;代码不是普通文本。函数、类、接口这些天然边界就是最合理的 chunk 粒度：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_discount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_type&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;根据用户类型计算折扣&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;vip&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentHandler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;支付处理器&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chunk1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;def calculate_discount(...)&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;# 函数级&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chunk2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;class PaymentHandler&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;# 类级&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：代码仓库的 RAG 问答。
&lt;strong&gt;优势&lt;/strong&gt;：每个 chunk 保留了一个逻辑单元（一个函数/类），检索命中后 LLM 可以完整理解这个单元的实现。&lt;/p&gt;
&lt;h3 id="策略4父子切割parent-child-chunking生产级推荐"&gt;策略4：父子切割（Parent-Child Chunking）【生产级推荐】
&lt;/h3&gt;&lt;p&gt;RAG 系统里有一个经典矛盾：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;chunk 越小，检索匹配越精准（粒度细）&lt;/li&gt;
&lt;li&gt;chunk 越大，LLM 阅读时上下文越完整（信息多）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;父子切割的解决思路&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用小块做检索（精准匹配）&lt;/li&gt;
&lt;li&gt;匹配命中后，返回这个 chunk 对应的大块（完整上下文）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 父 chunk（大块）:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 第3章 Python 数据类型
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 3.1 列表操作：列表是 Python 中最常用的数据类型之一...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [包含完整的章节内容]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 子 chunk（小块）:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 列表 append 方法使用说明
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; append(x) 在列表末尾添加元素...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 检索 &amp;#34;append 怎么用&amp;#34; → 命中子 chunk → 返回父 chunk 到 LLM
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：几乎所有生产级 RAG 都在用或应该用这个策略。
&lt;strong&gt;实现要点&lt;/strong&gt;：子 chunk 需要存储指向父 chunk 的引用 ID；检索时先查子 chunk，命中后取回对应的父 chunk 全文。&lt;/p&gt;
&lt;h2 id="三chunk-的-metadata-设计"&gt;三、Chunk 的 Metadata 设计
&lt;/h2&gt;&lt;p&gt;每个 chunk 存储时，除了 text 和 vector，还需要丰富的 metadata：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;列表 append 方法使用说明...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;vector&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.02&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;metadata&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;source_file&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;python_guide.md&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;chapter&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;3.1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tags&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;data_structure&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;doc_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;api_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;page_number&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2026-01-15&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;parent_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;chunk_3_1_parent&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;// 父子切割时使用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Metadata 的作用&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;过滤：只检索某个文件类型或某个分类，缩小搜索范围&lt;/li&gt;
&lt;li&gt;溯源：LLM 生成的答案可以标注来源出处&lt;/li&gt;
&lt;li&gt;去重：避免同一来源的 chunk 全部进答案&lt;/li&gt;
&lt;li&gt;父子关联：维系父子切割的关系映射&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="四切分粒度的黄金法则"&gt;四、切分粒度的黄金法则
&lt;/h2&gt;&lt;p&gt;没有绝对的「最优粒度」，取决于你的检索目标：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;检索目标&lt;/th&gt;
&lt;th&gt;推荐粒度&lt;/th&gt;
&lt;th&gt;原因&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;回答事实性问题&lt;/td&gt;
&lt;td&gt;句子/段落级&lt;/td&gt;
&lt;td&gt;需要精确匹配术语&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;回答解释性问题&lt;/td&gt;
&lt;td&gt;段落/章节级&lt;/td&gt;
&lt;td&gt;需要完整上下文才能理解&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;代码问答&lt;/td&gt;
&lt;td&gt;函数/类级&lt;/td&gt;
&lt;td&gt;保留逻辑单元，问答精准到函数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;支持多跳推理&lt;/td&gt;
&lt;td&gt;父子结构&lt;/td&gt;
&lt;td&gt;小块检索精准，大块总结完整&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;经验法则&lt;/strong&gt;：先按合理的中等粒度（500-1000 token）做基线，然后通过检索日志分析「有没有该命中没命中」「命中的是否相关」，再逐步调优。不要盲目追求小粒度——检索精度提升了，但 LLM 理解难度可能增加了。&lt;/p&gt;
&lt;h2 id="五常见-bad-case-及解决"&gt;五、常见 bad case 及解决
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;问题&lt;/th&gt;
&lt;th&gt;表现&lt;/th&gt;
&lt;th&gt;解决&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;语义被切断&lt;/td&gt;
&lt;td&gt;切在句子中间，LLM 收到后理解出错&lt;/td&gt;
&lt;td&gt;以语义边界为切分优先&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;信息密度不均匀&lt;/td&gt;
&lt;td&gt;有些 chunk 太空泛，有些太密集&lt;/td&gt;
&lt;td&gt;混合策略，或过滤短 chunk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;多语言混合&lt;/td&gt;
&lt;td&gt;中英混杂切分点不准确&lt;/td&gt;
&lt;td&gt;按 tokenizer 的 token 计数而非字符数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;过细噪音多&lt;/td&gt;
&lt;td&gt;切太小导致检索到很多无关碎片&lt;/td&gt;
&lt;td&gt;加最低长度阈值或使用父子结构&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;过粗精度低&lt;/td&gt;
&lt;td&gt;切太大细节信息被「平均掉」&lt;/td&gt;
&lt;td&gt;减小 chunk 大小或加摘要&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;PDF 文档的 chunking 特别难：解析出来的文本往往丧失段落结构，表格和代码块混在一起。对于这类文档，通常需要先做一次结构解析（用 PDF 解析器提取段落、表格、列表信息），然后再做语义 chunking。&lt;/p&gt;
&lt;h2 id="六本章小结"&gt;六、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Chunking 是 RAG 系统里最关键也最被低估的工程决策&lt;/li&gt;
&lt;li&gt;四大策略：固定大小（基线）、语义边界（结构化文档）、代码逻辑（代码库）、父子结构（兼顾精度+完整上下文）&lt;/li&gt;
&lt;li&gt;Metadata 设计能让你在检索时做精准过滤、溯源和去重&lt;/li&gt;
&lt;li&gt;没有统一的「最好粒度」，先跑基线、有数据再优化，比一把梭效果更稳定&lt;/li&gt;
&lt;li&gt;生产级推荐：父子切割（小块检索 + 大块返回），解决精度与完整性的天然矛盾&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;父子切割虽然好用，但实现上需要做父-子映射关系管理。你怎么设计这个映射系统，让它既高效又容错？&lt;/li&gt;
&lt;li&gt;对于 PDF 解析出来的文本（排版丢失、表格混乱），你有什么 chunking 策略？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第6章：RAG——给大模型一本「开卷考试」的参考资料</title><link>https://blog.irudder.me/ai/knowledge-series/06-What-is-RAG.html</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/06-What-is-RAG.html</guid><description>&lt;h1 id="第6章rag给大模型一本开卷考试的参考资料"&gt;第6章：RAG——给大模型一本「开卷考试」的参考资料
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：RAG 是 LLM 工程中最主流、最有实现价值的系统方案。从本章开始，建议认真跟完 RAG 模块（第6-11章），这是把 LLM 做成靠谱产品最关键的技术栈。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一rag-的定位解决-llm-的知识冻结问题"&gt;一、RAG 的定位：解决 LLM 的知识冻结问题
&lt;/h2&gt;&lt;p&gt;LLM 最大的硬伤是什么？&lt;strong&gt;知识被冻结在训练截止日期&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;你问它：「我们公司上个月发布了什么新功能？」它不知道。
你问它：「我的私人笔记里关于算法的那部分内容是什么？」它不知道。&lt;/p&gt;
&lt;p&gt;RAG 全称 &lt;strong&gt;Retrieval-Augmented Generation（检索增强生成）&lt;/strong&gt;，核心思路是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;在 LLM 生成答案之前，先从一个外部知识库里检索相关内容，把检索结果作为上下文喂给 LLM，让它基于这些参考资料来回答。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;这就好比把闭卷考试改成了开卷考试——LLM 不需要背诵所有知识，考试时现场翻资料就行了。&lt;/p&gt;
&lt;h2 id="二rag-完整工作流一句话--一张图"&gt;二、RAG 完整工作流（一句话 + 一张图）
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户提问 → 预处理/改写 → 向量化 → 向量数据库检索 →
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;粗排/精排 → 拼装 Prompt → LLM 基于参考资料生成答案 → 答案
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;整个过程分两条线：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;离线线&lt;/strong&gt;：文档 → 切割 → 向量化 → 存入向量数据库（一次性预处理）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在线线&lt;/strong&gt;：用户提问 → 检索 → 生成答案（每次用户提问都走）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="三离线阶段把文档变成可检索的向量"&gt;三、离线阶段：把文档变成可检索的向量
&lt;/h2&gt;&lt;h3 id="步骤1文档切割chunking"&gt;步骤1：文档切割（Chunking）
&lt;/h3&gt;&lt;p&gt;原始文档不能整篇直接存入向量库，因为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Embedding 模型有输入长度限制（通常几百到几千 token）&lt;/li&gt;
&lt;li&gt;长文档压缩成一个向量会「平均掉」细节，检索精度极低&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以必须**切成小块（chunk）**存储。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;常见切割策略&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;策略&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;th&gt;优缺点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;固定大小 + 重叠&lt;/td&gt;
&lt;td&gt;通用文本&lt;/td&gt;
&lt;td&gt;简单，可能切到句中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;按语义边界切&lt;/td&gt;
&lt;td&gt;有章节结构的文档&lt;/td&gt;
&lt;td&gt;语意完整，实现稍复杂&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;按函数/类切&lt;/td&gt;
&lt;td&gt;代码文件&lt;/td&gt;
&lt;td&gt;保持代码逻辑单元完整&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;父子切割&lt;/td&gt;
&lt;td&gt;精度+全文都要&lt;/td&gt;
&lt;td&gt;小块检索，大块返回&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;每条 chunk 包含三部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;向量&lt;/strong&gt;：用于相似度检索&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原始文本&lt;/strong&gt;：检索命中后塞给 LLM 读的内容&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metadata&lt;/strong&gt;：来源文件、页码、分类等附加信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="步骤2embedding-向量化"&gt;步骤2：Embedding 向量化
&lt;/h3&gt;&lt;p&gt;Embedding 是一种「语义压缩」——把文本映射成一个固定长度的浮点数向量。&lt;/p&gt;
&lt;p&gt;核心性质：&lt;strong&gt;语义相近的文本，向量距离就相近&lt;/strong&gt;（通常用余弦相似度衡量）。&lt;/p&gt;
&lt;p&gt;举个例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;猫坐在垫子上&amp;rdquo; 和 &amp;ldquo;小猫趴在毯子上面&amp;rdquo; → 向量距离很近&lt;/li&gt;
&lt;li&gt;&amp;ldquo;猫坐在垫子上&amp;rdquo; 和 &amp;ldquo;股票价格今日大涨&amp;rdquo; → 向量距离很远&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;选择 Embedding 模型的关键考量：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;语言支持&lt;/strong&gt;：中文场景首选 BGE 系列、M3E、智谱 Embedding&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;向量维度&lt;/strong&gt;：维度越高精度越好，但存储成本也越大（常见 384-4096 维）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最大输入长度&lt;/strong&gt;：决定能处理多长的 chunk（常见 512-8192 token）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;评估&lt;/strong&gt;：不要只看排行榜，要在&lt;strong&gt;你自己的数据&lt;/strong&gt;上测召回率（Hit@K、NDCG@K）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="步骤3存入向量数据库"&gt;步骤3：存入向量数据库
&lt;/h3&gt;&lt;p&gt;向量数据库是专门存储和检索高维向量的数据库，核心能力是&lt;strong&gt;近似最近邻搜索（ANN）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;在大规模（百万甚至亿级）向量中，它能在毫秒级找出最相似的几条。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不是「在 MySQL 里加个 float 数组」，也不是用 LIKE 字符串匹配&lt;/strong&gt;——向量相似度搜索在算法层（HNSW、IVF-PQ）和硬件层（SIMD 指令、GPU 加速）专门做了优化。&lt;/p&gt;
&lt;h2 id="四在线阶段从用户提问到最终答案"&gt;四、在线阶段：从用户提问到最终答案
&lt;/h2&gt;&lt;h3 id="步骤1query-预处理"&gt;步骤1：Query 预处理
&lt;/h3&gt;&lt;p&gt;用户问「这个功能怎么用」，知识库里写的是「XX 模块操作指南」。&lt;/p&gt;
&lt;p&gt;口语化的问题和正式文档表述之间存在&lt;strong&gt;语义鸿沟&lt;/strong&gt;，直接检索效果很差。&lt;/p&gt;
&lt;p&gt;解决方案：Query Rewrite（查询改写）。方法包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;直接改写&lt;/strong&gt;：让 LLM 把口语问题转成规范表述&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Query 扩展&lt;/strong&gt;：补充相关关键词&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HyDE（假设文档嵌入）&lt;/strong&gt;：让 LLM 先假设一个答案，用这个答案的向量去检索（隐性扩展匹配面）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Step-back Prompting&lt;/strong&gt;：把具体问题抽象一层，检索更通用的背景知识&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="步骤2向量检索"&gt;步骤2：向量检索
&lt;/h3&gt;&lt;p&gt;把改写后的查询向量化，去向量库中搜索最相似的 Top-K 个 chunk。&lt;/p&gt;
&lt;p&gt;这一步叫 &lt;strong&gt;粗排（Retrieval）&lt;/strong&gt;，目标是「尽可能多地把相关内容召回来」（召回优先）。&lt;/p&gt;
&lt;h3 id="步骤3重排序rerank"&gt;步骤3：重排序（Rerank）
&lt;/h3&gt;&lt;p&gt;粗排召回的 Top-K 中可能包含很多不相关的内容（噪音）。&lt;/p&gt;
&lt;p&gt;Rerank（重排序）用更精确的模型（如 BGE-Reranker）对粗排结果打分，只保留最相关的几条，把参数量降低同时提高精度。&lt;/p&gt;
&lt;h3 id="步骤4prompt-拼装与生成"&gt;步骤4：Prompt 拼装与生成
&lt;/h3&gt;&lt;p&gt;把筛选后的 chunk 和用户问题一起拼成 prompt：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;请基于以下参考资料回答问题：
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[参考资料1]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[参考资料2]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;问题是：用户的问题是什么？
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;请只基于以上参考资料作答。如果资料中找不到答案，请明确说明&amp;#34;无法从已有资料中找到相关信息&amp;#34;。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;关键设计&lt;/strong&gt;：强制要求模型只基于参考资料回答，有效防止幻觉和编造。&lt;/p&gt;
&lt;h2 id="五rag-vs-微调fine-tuning"&gt;五、RAG vs 微调（Fine-tuning）
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;RAG&lt;/th&gt;
&lt;th&gt;微调&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;原理&lt;/td&gt;
&lt;td&gt;动态检索外部知识&lt;/td&gt;
&lt;td&gt;修改模型参数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知识更新&lt;/td&gt;
&lt;td&gt;即时替换文档即可&lt;/td&gt;
&lt;td&gt;需要重新训练&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;成本&lt;/td&gt;
&lt;td&gt;低（向量库查询+LLM调用）&lt;/td&gt;
&lt;td&gt;高（训练计算+标注数据）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;通用效果&lt;/td&gt;
&lt;td&gt;适合知识密集型任务&lt;/td&gt;
&lt;td&gt;适合风格/格式适应&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可解释性&lt;/td&gt;
&lt;td&gt;好（可追溯来源）&lt;/td&gt;
&lt;td&gt;差（参数变化不可见）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;经验法则&lt;/strong&gt;：先上 RAG，RAG 真不够用再考虑微调。90% 的知识问答场景用 RAG 就够了。&lt;/p&gt;
&lt;h2 id="六知识问答场景的-rag-六边形"&gt;六、知识问答场景的 RAG 六边形
&lt;/h2&gt;&lt;p&gt;一个成熟的 RAG 系统至少要考虑：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;文档解析&lt;/strong&gt;：PDF/Word/Excel/网页等各种格式的读取&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;切割策略&lt;/strong&gt;：用什么粒度、什么策略切 chunk&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Embedding 选型&lt;/strong&gt;：用什么模型、什么维度&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;向量库选型&lt;/strong&gt;：规模多大、需要实时更新吗&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;检索优化&lt;/strong&gt;：粗排+Rerank+多路召回&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成控制&lt;/strong&gt;：Prompt 设计、幻觉规避、引用来源&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="七本章小结"&gt;七、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;RAG = 检索 + 生成，解决 LLM 知识冻结问题&lt;/li&gt;
&lt;li&gt;离线线：切分 → Embedding → 存向量库&lt;/li&gt;
&lt;li&gt;在线线：Query改写 → 向量检索 → Rerank精排 → Prompt拼装 → LLM生成&lt;/li&gt;
&lt;li&gt;选 RAG 还是微调：先 RAG，真的不行再上微调&lt;/li&gt;
&lt;li&gt;RAG 的本质是给 LLM 提供有据可查的上下文，把闭卷考试改成开卷考试→减少幻觉、增加可解释性、知识实时更新&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;为什么 Embedding 模型在通用数据集上的排行榜分数不能直接代表你的业务场景效果？&lt;/li&gt;
&lt;li&gt;如果你要构建一个企业内部文档问答系统，哪些环节最可能拖慢你的开发进度？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第5章：MCP——工具调用的标准化革命</title><link>https://blog.irudder.me/ai/knowledge-series/05-MCP-and-Protocolized-Tool-Ecosystem.html</link><pubDate>Mon, 01 Jun 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/05-MCP-and-Protocolized-Tool-Ecosystem.html</guid><description>&lt;h1 id="第5章mcp工具调用的标准化革命"&gt;第5章：MCP——工具调用的标准化革命
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：本章是上章的延伸。如果你还在手写每个工具的集成代码，MCP 就是来救你的。它能让你接入一个工具的效率从「一天」降到「十分钟」。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id="一没有-mcp-之前接工具有多麻烦"&gt;一、没有 MCP 之前，接工具有多麻烦？
&lt;/h2&gt;&lt;p&gt;想象你要给 Claude Desktop 接入三个工具：GitHub（查仓库）、文件系统（读本地文件）、Slack（发通知）。&lt;/p&gt;
&lt;p&gt;在没有 MCP 之前：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;写 GitHub API 调用代码 + OAuth 认证 + 错误处理 + 格式转换，确保返回结果能被模型理解&lt;/li&gt;
&lt;li&gt;写文件系统操作代码 + 权限管控 + 路径沙箱，防止模型删除不该删的文件&lt;/li&gt;
&lt;li&gt;写 Slack API 调用代码 + Bot 配置 + 消息格式化&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;折腾了三周，终于接好了。三个月后 Claude 升级了，接口变了，你的代码又得重写。&lt;/p&gt;
&lt;p&gt;最致命的问题：每个工具都要单独集成，而且强绑定到某个模型。你想换 Gemini 用这些工具？之前写的所有代码都要重写一遍嫁接逻辑。更别说换个多模态模型（比如能看图、能听语音的），工具 layer 可能完全不兼容。&lt;/p&gt;
&lt;p&gt;这种碎片化的结果就是：目前市面上有成百上千个有用的工具 API，开发者和模型提供者之间形成了一个糟糕的分发瓶颈——每一家模型厂都要跟每一家工具厂谈合作、做适配。&lt;/p&gt;
&lt;h2 id="二mcp-是什么"&gt;二、MCP 是什么？
&lt;/h2&gt;&lt;p&gt;MCP（Model Context Protocol，模型上下文协议）是 Anthropic 在 2024 年底推出的开放协议（不是框架，是协议）。&lt;/p&gt;
&lt;p&gt;它的核心目标是：工具实现一次，到处复用；任何支持 MCP 的 AI 客户端，都能自动发现并接入。&lt;/p&gt;
&lt;p&gt;你可以把它理解成 AI 时代的「USB-C 接口」——所有工具都按统一标准做接口，所有 AI 客户端都支持这个接口。工具提供者按协议标准写一个 Server，任何支持 MCP 的客户端都能直接拿来用，不需要再说服 OpenAI 或 Google 专门为你做对接。&lt;/p&gt;
&lt;h2 id="三mcp-的架构client-server-模式"&gt;三、MCP 的架构：Client-Server 模式
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌──────────────┐ ┌──────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ AI Client │ ←─── MCP 协议 ───→ │ MCP Server 1 │ (GitHub工具)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ (Claude, │ JSON-RPC 2.0 └──────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ OpenAI SDK) │ ┌──────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │ ←─── MCP 协议 ───→ │ MCP Server 2 │ (文件系统)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──────────────┘ (stdio / SSE / HTTP) └──────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;MCP Server：每个工具按 MCP 协议实现一个服务进程，暴露能力&lt;/li&gt;
&lt;li&gt;AI Client：在配置文件中声明 MCP Server 地址，自动发现可用的工具&lt;/li&gt;
&lt;li&gt;通信方式：支持 stdio（本地进程）、SSE（HTTP流式）、HTTP（远程调用）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种设计的妙处在于：工具提供者只需要写一份标准化的 Server 实现，所有客户端（Claude、OpenAI SDK、Cursor IDE、Zed 编辑器等）都能自动发现并调用它的能力。工具生态的分发效率得到了本质提升。&lt;/p&gt;
&lt;h2 id="四mcp-的三类核心能力"&gt;四、MCP 的三类核心能力
&lt;/h2&gt;&lt;h3 id="1-tools工具-执行有副作用的操作"&gt;1. Tools（工具）—— 执行有副作用的操作
&lt;/h3&gt;&lt;p&gt;如发送邮件、创建文件、调用 API。每次调用都可能改变外部世界状态。工具调用后需要返回执行结果给模型，模型据此决定下一步。&lt;/p&gt;
&lt;h3 id="2-resources资源-只读数据通道"&gt;2. Resources（资源）—— 只读数据通道
&lt;/h3&gt;&lt;p&gt;如读取文件内容、访问数据库、查看日志。资源可以被&amp;quot;挂载&amp;quot;到客户端上下文，模型可以随时调用，不会产生副作用。&lt;/p&gt;
&lt;h3 id="3-prompts提示词模板-结构化输入模板"&gt;3. Prompts（提示词模板）—— 结构化输入模板
&lt;/h3&gt;&lt;p&gt;预定义一组任务模板，用户可以在使用前填充参数。比如 &amp;ldquo;生成代码审查提示词&amp;rdquo; → 填充 &amp;ldquo;文件路径&amp;rdquo; → 拿到完整 prompt。这类能力让 MCP Server 不仅是被动的工具提供者，也是主动的交互助手。&lt;/p&gt;
&lt;p&gt;这三类能力覆盖了 AI 工具生态中的&amp;quot;执行&amp;quot;、&amp;ldquo;读取&amp;rdquo;、&amp;ldquo;交互模板&amp;quot;三个核心场景。&lt;/p&gt;
&lt;h2 id="五mcp-vs-function-calling不是替代是互补"&gt;五、MCP vs Function Calling：不是替代，是互补
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;Function Calling&lt;/th&gt;
&lt;th&gt;MCP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;层级&lt;/td&gt;
&lt;td&gt;API 调用格式（命令）&lt;/td&gt;
&lt;td&gt;工具生态协议 + 发现机制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;解决的问题&lt;/td&gt;
&lt;td&gt;模型怎么说出「我要调什么」&lt;/td&gt;
&lt;td&gt;工具怎么被接入和管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;类比&lt;/td&gt;
&lt;td&gt;HTTP 请求格式&lt;/td&gt;
&lt;td&gt;REST API 规范 + 服务注册发现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;关系&lt;/td&gt;
&lt;td&gt;依赖关系&lt;/td&gt;
&lt;td&gt;MCP 底层还是靠 Function Calling！&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;最关键的一句话：MCP 底层驱动的仍然是 Function Calling。MCP 不是「不用 Function Calling 了」，而是在 Function Calling 之上加了一层生态层。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Function Calling 说：模型输出的工具调用应该是 JSON Schema 格式&lt;/li&gt;
&lt;li&gt;MCP 说：工具怎么注册、怎么发现、怎么通信、怎么复用，都按统一标准来&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你可以只靠 Function Calling 写一辈子代码，但接入第10个工具时你就会想要 MCP。手动管理10个工具的 schema、认证、状态同步、错误重试，是在做重复的体力活。&lt;/p&gt;
&lt;h2 id="六配置一个-mcp-server-有多简单"&gt;六、配置一个 MCP Server 有多简单？
&lt;/h2&gt;&lt;p&gt;以 Claude Desktop 为例，它的配置文件中加几行就行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mcpServers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;filesystem&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;npx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-y&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@modelcontextprotocol/server-filesystem&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/Users/me/docs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;github&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;npx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-y&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@modelcontextprotocol/server-github&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;env&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;GITHUB_PERSONAL_ACCESS_TOKEN&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ghp_xxx&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;启动 Claude Desktop 后：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;自动启动各 MCP Server 进程&lt;/li&gt;
&lt;li&gt;读取各 Server 暴露的 tools/resources/prompts 列表&lt;/li&gt;
&lt;li&gt;Claude 自动发现这些工具并能随时调用&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;零代码接入。&lt;/p&gt;
&lt;h2 id="七mcp-对生态的影响"&gt;七、MCP 对生态的影响
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;工具开发者：按 MCP 标准实现一次，OpenAI、Claude、Gemini 都能用。分发成本从 O(NxM) 降到 O(N+M)。&lt;/li&gt;
&lt;li&gt;AI 客户端开发者：接入 MCP 协议就能自动获得成百上千的工具&lt;/li&gt;
&lt;li&gt;终端用户：AI 能做的事情从「聊天+联网搜索」变成「调用整个数字世界&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MCP 的意义跟当年 HTTP 协议标准化 web 服务是一样的底层逻辑。如果没有 HTTP，每个网站都得写自己的传输协议，浏览器永远做不到通用。MCP 的目标是让 AI 工具的接入也有同样的标准化基础。&lt;/p&gt;
&lt;h2 id="八本章小结"&gt;八、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;MCP 是 AI 工具生态的&amp;quot;USB-C&amp;quot;标准化协议&lt;/li&gt;
&lt;li&gt;三类能力：Tools（执行）、Resources（只读数据）、Prompts（模板）&lt;/li&gt;
&lt;li&gt;MCP 和 Function Calling 是不同层次的东西：FC 解决&amp;quot;格式&amp;quot;问题，MCP 解决&amp;quot;生态&amp;quot;问题&lt;/li&gt;
&lt;li&gt;配置 MCP Server 只需几行配置，零代码接入&lt;/li&gt;
&lt;li&gt;MCP 代表了 AI 工具生态从碎片化走向标准化的关键转折点&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;MCP 的「开放协议」定位意味着它的生命周期会长于任何单一公司的产品。如果这个协议成为事实标准，会对 AI 工具生态产生什么深远影响？&lt;/li&gt;
&lt;li&gt;在 MCP 的三种能力（Tools/Resources/Prompts）中，你认为哪一类最有商业想象空间？为什么？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第4章：Function Calling——让大模型从「聊天者」变成「执行者」</title><link>https://blog.irudder.me/ai/knowledge-series/04-Function-Calling.html</link><pubDate>Sat, 30 May 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/04-Function-Calling.html</guid><description>&lt;h1 id="第4章function-calling让大模型从聊天者变成执行者"&gt;第4章：Function Calling——让大模型从「聊天者」变成「执行者」
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：从本章开始，我们进入 LLM 的「行动能力」阶段。如果你还没看第1章，建议先了解 LLM 的本质，再去理解为什么它能「调用工具」是真正的事半功倍。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一function-calling-到底是什么"&gt;一、Function Calling 到底是什么？
&lt;/h2&gt;&lt;p&gt;LLM 本身是一个&lt;strong&gt;文本生成器&lt;/strong&gt;，它生成了天气查询请求，但它不能自己去调用 API。&lt;/p&gt;
&lt;p&gt;Function Calling（工具调用）就是解决这个问题的机制：让 LLM &lt;strong&gt;输出结构化的工具调用指令&lt;/strong&gt;（通常是 JSON 格式），你的代码负责解析并执行真实的调用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心原则&lt;/strong&gt;：模型只判断「该做什么」，代码负责「真正把它做了」。&lt;/p&gt;
&lt;h2 id="二function-calling-的两轮对话流程"&gt;二、Function Calling 的两轮对话流程
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;用户提问&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;LLM&lt;/span&gt; &lt;span class="err"&gt;判断需要调工具&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;输出&lt;/span&gt; &lt;span class="n"&gt;tool_call&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;代码解析&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;真正调用&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;获得结果&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;把结果塞回对话&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;LLM&lt;/span&gt; &lt;span class="err"&gt;生成最终答案&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这是最基础的流程，实际可能有多次工具调用循环。&lt;/p&gt;
&lt;h3 id="具体例子"&gt;具体例子
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Round 1 - 用户输入：&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;北京今天的天气怎么样？&amp;rdquo;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Round 1 - LLM 响应（不是答案，是工具调用指令）：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tool_calls&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;call_abc123&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;function&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;function&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;get_weather&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;arguments&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;{\&amp;#34;city\&amp;#34;: \&amp;#34;北京\&amp;#34;, \&amp;#34;date\&amp;#34;: \&amp;#34;2026-07-21\&amp;#34;}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;代码层 - 解析并执行：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tool_call&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tool_call&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;get_weather&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_call&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;date&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Round 2 - 把结果塞回对话：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;北京今天的天气怎么样？&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Assistant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tool_call&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;北京&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2026-07-21&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;temperature&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;condition&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;晴&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;humidity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;65%&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Assistant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;北京今天晴天，气温&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="err"&gt;℃，湿度&lt;/span&gt; &lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="err"&gt;，非常适合户外活动！&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="三schema-定义关键工程细节"&gt;三、Schema 定义：关键工程细节
&lt;/h2&gt;&lt;p&gt;Function Calling 的核心是 schema 的定义。schema 告诉模型每个工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;name&lt;/strong&gt;：工具名称，越具体越好&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;description&lt;/strong&gt;：工具的详细用途，模型靠这个决定要不要调它&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;parameters&lt;/strong&gt;：参数结构，包含每个参数名、类型、描述、是否必填&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;required&lt;/strong&gt;：必填参数列表&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Schema 示例&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;get_weather&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;获取指定城市和日期的天气信息，包括温度、天气状况、湿度。支持中国境内城市。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;parameters&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;要查询天气的城市名称，例如：北京、上海、广州&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;date&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;查询日期，格式为 YYYY-MM-DD&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;required&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;date&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;description 是最关键的字段&lt;/strong&gt;。模型完全靠 description 来判断该不该调这个工具。写 description 的技巧：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;明确边界&lt;/strong&gt;：不是什么都调，只在什么场景下调&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;给出例子&lt;/strong&gt;：比如 &amp;ldquo;当用户问 xx 时调用&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;避免触发词陷阱&lt;/strong&gt;：description里别用模型的名字（如 &amp;ldquo;ChatGPT&amp;rdquo;），否则模型可能误触发&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="四function-calling-和土办法的区别"&gt;四、Function Calling 和「土办法」的区别
&lt;/h2&gt;&lt;p&gt;在没有 Function Calling 之前，开发者只能靠解析自然语言文本来判断模型要不要调工具：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 土办法&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;帮我查北京天气&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;天气&amp;#34;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 手动解析，极其脆弱&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extract_city&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 容易出错&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Function Calling 以后：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Function Calling 方式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;帮我查北京天气&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;weather_tool_schema&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 模型输出的是结构化 JSON，解析安全得多&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tool_call&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;关键区别：&lt;strong&gt;结构化输出 vs 自然语言解析&lt;/strong&gt;。结构化输出准确率接近100%，自然语言解析经常抽风。&lt;/p&gt;
&lt;h2 id="五高级特性"&gt;五、高级特性
&lt;/h2&gt;&lt;h3 id="1-并行工具调用"&gt;1. 并行工具调用
&lt;/h3&gt;&lt;p&gt;模型可能在一次响应中输出多个 tool_calls，比如用户问&amp;quot;北京和上海的天气&amp;quot;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tool_calls&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;function&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;get_weather&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;arguments&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;{\&amp;#34;city\&amp;#34;: \&amp;#34;北京\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;function&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;get_weather&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;arguments&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;{\&amp;#34;city\&amp;#34;: \&amp;#34;上海\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;你的代码可以并行执行两个调用，然后再把结果一起塞回去。&lt;/p&gt;
&lt;h3 id="2-强制使用工具"&gt;2. 强制使用工具
&lt;/h3&gt;&lt;p&gt;有些场景要求模型&lt;strong&gt;必须&lt;/strong&gt;调工具，不提供直接回答：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool_choice&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;required&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 设置 tool_choice 为 &amp;#34;required&amp;#34; 强制模型输出 tool_calls&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="3-多轮工具调用链"&gt;3. 多轮工具调用链
&lt;/h3&gt;&lt;p&gt;复杂任务可能需要多次调用：查天气 → 根据温度推荐衣服 → 查找推荐店铺的地址 → 查询交通路线。&lt;/p&gt;
&lt;p&gt;每一轮把结果塞回 history，LLM 自动判断下一步该做什么。这就是 Agent 的基础。&lt;/p&gt;
&lt;h2 id="六常见坑"&gt;六、常见坑
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;坑&lt;/th&gt;
&lt;th&gt;解决方案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;模型选错工具&lt;/td&gt;
&lt;td&gt;description 写清楚边界 + 用 tool_choice 限制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;参数类型错误&lt;/td&gt;
&lt;td&gt;schema 中严格定义 enum/number/string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;函数结果太长塞爆 context&lt;/td&gt;
&lt;td&gt;摘要压缩后返回&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;工具调用死循环&lt;/td&gt;
&lt;td&gt;max_iterations 限制 + 超时熔断&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;结果格式不一致&lt;/td&gt;
&lt;td&gt;在 function result 中也标准化输出格式&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="七本章小结"&gt;七、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Function Calling = 模型决策 + 代码执行，两者严格分离&lt;/li&gt;
&lt;li&gt;Schema description 是核心，决定了模型是否选对工具、传对参数&lt;/li&gt;
&lt;li&gt;并行调用、强制调用、多轮链式调用是高级用法&lt;/li&gt;
&lt;li&gt;它是通往 Agent 的必经之路&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;为什么 Function Calling 要求模型输出的是 JSON schema 而不是自由文本？这背后的设计哲学是什么？&lt;/li&gt;
&lt;li&gt;如果模型的 tool_calls 返回的参数含危险操作（如删除文件），你的拦截策略应该放在哪一层？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第2章：Transformer架构——LLM的心脏，你必须了解的结构</title><link>https://blog.irudder.me/ai/knowledge-series/02-Transformer-Architecture-Explained.html</link><pubDate>Fri, 29 May 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/02-Transformer-Architecture-Explained.html</guid><description>&lt;h1 id="第2章transformer架构llm的心脏你必须了解的结构"&gt;第2章：Transformer架构——LLM的心脏，你必须了解的结构
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：本章是系列中最偏技术原理的一章。如果你不需要深挖底层，可以跳过神经网络和注意力机制的具体数学，但&lt;strong&gt;Attention 机制的概念&lt;/strong&gt;建议不要跳过，它是理解一切 LLM 能力的基础。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一为什么-transformer-如此重要"&gt;一、为什么 Transformer 如此重要？
&lt;/h2&gt;&lt;p&gt;在 Transformer 之前，NLP 主要用 RNN（循环神经网络）和 LSTM（长短期记忆网络）。它们的致命问题在于：&lt;strong&gt;无法并行计算&lt;/strong&gt;——处理一个句子，必须一个词一个词地按顺序来，后面的词必须等前面的处理完。&lt;/p&gt;
&lt;p&gt;Transformer（2017年 Google 提出，论文《Attention Is All You Need》）革命性地用**自注意力机制（Self-Attention）**替代了顺序依赖，实现了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;全并行计算&lt;/strong&gt;：句子中所有词同时处理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无限感知距离&lt;/strong&gt;：一个词可以直接「看到」句子里的任何一个词，无论多远&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;极强的可扩展性&lt;/strong&gt;：奠定了「大」模型的基础&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="二transformer-的整体架构"&gt;二、Transformer 的整体架构
&lt;/h2&gt;&lt;p&gt;LLM（尤其是 GPT 系列）用的是 &lt;strong&gt;Decoder-only&lt;/strong&gt; 架构，只保留 Transformer 的解码器部分。一张图说清楚：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;输入文本 → Token Embedding + 位置编码 → N个解码器层 → 输出概率分布 → 选词 → 生成文本
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;每层解码器内部包含两个核心子模块：&lt;/p&gt;
&lt;h3 id="1-多头自注意力multi-head-self-attention"&gt;1. 多头自注意力（Multi-Head Self-Attention）
&lt;/h3&gt;&lt;p&gt;这是 Transformer 的灵魂。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自注意力的核心思想&lt;/strong&gt;：计算句子中&lt;strong&gt;每个词与其他所有词之间的关联强度&lt;/strong&gt;，然后根据关联强度加权聚合信息。&lt;/p&gt;
&lt;p&gt;比如输入句子：「猫坐在垫子上，因为它很暖和。」&lt;/p&gt;
&lt;p&gt;传统序列模型处理「它」时，只能看到前面的词，难以判断「它」到底指猫还是垫子。而 Transformer 的注意力机制让「它」直接去「问」前面的所有词：「你跟我关系近吗？」&lt;/p&gt;
&lt;p&gt;结果「垫子」和「暖和」得分最高，「猫」得分次之——模型就明白「它=垫子」了。&lt;/p&gt;
&lt;h4 id="三步走query-key-value"&gt;三步走：Query, Key, Value
&lt;/h4&gt;&lt;p&gt;这是注意力机制最经典也最容易被误解的部分。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每个词拿出一组「查询向量」（Query）：&amp;ldquo;我有问题要问别人&amp;rdquo;&lt;/li&gt;
&lt;li&gt;每个词拿出一组「键向量」（Key）：&amp;ldquo;这是我对自己的描述，来和我匹配&amp;rdquo;&lt;/li&gt;
&lt;li&gt;每个词拿出一组「值向量」（Value）：&amp;ldquo;如果匹配上了，这是我贡献的信息&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;过程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;每个词的 Query 向量，与所有词的 Key 向量做点积 → 得到一个注意力分数&lt;/li&gt;
&lt;li&gt;分数经过 softmax 归一化 → 得到权重&lt;/li&gt;
&lt;li&gt;用权重加权所有词的 Value 向量 → 得到这个词的新表示&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;数学公式：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Attention(Q, K, V) = softmax(Q·K^T / sqrt(d_k)) · V
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;除以 sqrt(d_k) 的缩放步骤——在维度很高时，点积结果会变得极大，softmax 会退化成接近 one-hot 的极端分布，缩放可以平滑它。&lt;/p&gt;
&lt;h4 id="多头multi-head"&gt;多头（Multi-Head）
&lt;/h4&gt;&lt;p&gt;一套 Query/Key/Value 不够用，来多套——比如8套或16套。&lt;/p&gt;
&lt;p&gt;每套「头」关注不同的语言模式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第1个头关注语法关系（主语-谓语）&lt;/li&gt;
&lt;li&gt;第2个头关注语义相似度&lt;/li&gt;
&lt;li&gt;第3个头关注位置相邻关系&lt;/li&gt;
&lt;li&gt;第4个头关注代词指代&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后把多个头的结果拼接起来，用一个线性变换合并。多头让每个数学空间「各司其职」，信息更丰富。&lt;/p&gt;
&lt;h3 id="2-前馈神经网络feed-forward-network-ffn"&gt;2. 前馈神经网络（Feed-Forward Network, FFN）
&lt;/h3&gt;&lt;p&gt;自注意力之后，每个词向量经过两层全连接网络：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;FFN(x) = ReLU(xW1 + b1)W2 + b2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;它的作用是把注意力的结果做一个&lt;strong&gt;非线性映射&lt;/strong&gt;，增加模型的表达能力。你可以把它理解为让每个词在注意力的基础上「深度加工」一下。&lt;/p&gt;
&lt;p&gt;现代大模型常用 GELU 或 SwiGLU 替代 ReLU，性能更好。&lt;/p&gt;
&lt;h2 id="三位置编码为什么需要它"&gt;三、位置编码：为什么需要它？
&lt;/h2&gt;&lt;p&gt;Transformer 的注意力机制是「全连接」的——它不在乎词在句子中的位置。但自然语言里位置极重要：「我打你」和「你打我」意思完全不同。&lt;/p&gt;
&lt;p&gt;位置编码（Positional Encoding）就用来注入位置信息。早期用正弦余弦函数生成位置向量，加到词向量上。现代大模型多用&lt;strong&gt;可学习的位置嵌入&lt;/strong&gt;（Learnable Positional Embedding）或&lt;strong&gt;旋转位置编码（RoPE）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;**RoPE（旋转位置编码）**是当代大模型（LLaMA、智谱、通义等）的主流选择。思路很巧妙：&lt;/p&gt;
&lt;p&gt;不把位置信息作为外部向量注入，而是让注意力计算中的 Query 和 Key 向量根据距离做「旋转」，旋转角度由位置决定，距离越远旋转角度越大。这样模型能学习到「距离越远的词，关联越弱」的偏置。&lt;/p&gt;
&lt;h2 id="四layer-normalization训练稳定的基石"&gt;四、Layer Normalization：训练稳定的基石
&lt;/h2&gt;&lt;p&gt;Transformer 层数很深（GPT-3 有96层），深网络里信号的分布会一层层漂移，导致训练不稳定。&lt;/p&gt;
&lt;p&gt;Layer Norm 在每一层内部对输入进行归一化，把值拉到均值为0、方差为1的分布。这样多层叠加时信号不会爆炸也不会消失。&lt;/p&gt;
&lt;p&gt;现代变体常用 &lt;strong&gt;RMSNorm&lt;/strong&gt;（Root Mean Square Norm），计算更简洁，LLaMA 等模型在用。&lt;/p&gt;
&lt;h2 id="五现代-llm-对-transformer-的改造"&gt;五、现代 LLM 对 Transformer 的改造
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;原设计&lt;/th&gt;
&lt;th&gt;改进&lt;/th&gt;
&lt;th&gt;代表模型&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LayerNorm → 先归一化再注意力&lt;/td&gt;
&lt;td&gt;Pre-Norm：先归一化再进入子层&lt;/td&gt;
&lt;td&gt;GPT-3、LLaMA 等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ReLU 激活&lt;/td&gt;
&lt;td&gt;SwiGLU/GELU 激活&lt;/td&gt;
&lt;td&gt;GPT-4、LLaMA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;原版位置编码&lt;/td&gt;
&lt;td&gt;RoPE 旋转位置编码&lt;/td&gt;
&lt;td&gt;LLaMA、智谱&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;全部密集层&lt;/td&gt;
&lt;td&gt;MoE（混合专家）稀疏激活&lt;/td&gt;
&lt;td&gt;Mixtral、GPT-4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;全局注意力&lt;/td&gt;
&lt;td&gt;滑动窗口注意力/稀疏注意力&lt;/td&gt;
&lt;td&gt;Longformer、Mistral&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="六为什么理解-transformer-结构很重要"&gt;六、为什么理解 Transformer 结构很重要？
&lt;/h2&gt;&lt;p&gt;你可以「用」GPT 而不了解 Transformer，但如果你要做 LLM 工程优化，以下问题都绕不开底层结构：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;KV Cache 优化&lt;/strong&gt;：Transformer 解码时每步都要计算所有 Key 和 Value，重算太浪费。缓存历史 KV 能把时间复杂度从 O(n²) 降到 O(n)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注意力幻方&lt;/strong&gt;：长上下文时自注意力的计算复杂度是 O(n²)，这是 LLM 最大的性能瓶颈。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;量化推理（8bit/4bit）&lt;/strong&gt;：知道矩阵乘法的内部结构，才知道哪些权重可以降精度而不影响效果。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prompt 压缩&lt;/strong&gt;：理解位置编码和注意力的偏置，才知道如何让模型更关注关键信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="七本章小结"&gt;七、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Transformer = 自注意力 + 前馈 + 位置编码，三者缺一不可&lt;/li&gt;
&lt;li&gt;自注意力让任意两个词之间直接通信，打破了序列模型的时间依赖&lt;/li&gt;
&lt;li&gt;Multi-Head 让多维度语义模式并行计算&lt;/li&gt;
&lt;li&gt;现代大模型在位置编码、归一化方式、激活函数上做了显著优化&lt;/li&gt;
&lt;li&gt;Transformer 架构的天花板决定了 LLM 能力的上限：O(n²) 的注意力复杂度是核心瓶颈&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;为什么 Transformer 的自注意力是 O(n²)，这对长上下文意味着什么？&lt;/li&gt;
&lt;li&gt;多头注意力中，不同的「头」真的会学到不同的模式吗？你怎么验证这件事？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第3章：大模型幻觉——它为什么胡说八道？如何让它老实？</title><link>https://blog.irudder.me/ai/knowledge-series/03-Hallucination-and-Controllability.html</link><pubDate>Fri, 29 May 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/03-Hallucination-and-Controllability.html</guid><description>&lt;h1 id="第3章大模型幻觉它为什么胡说八道如何让它老实"&gt;第3章：大模型幻觉——它为什么胡说八道？如何让它老实？
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：从本章开始，我们从「原理认知」转向「工程控制」。理解幻觉的成因，是构建可靠 AI 系统的第一步。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id="一什么是幻觉"&gt;一、什么是幻觉？
&lt;/h2&gt;&lt;p&gt;当你问 GPT-4：「鲁迅和周树人是什么关系？」&lt;/p&gt;
&lt;p&gt;它可能回答：「鲁迅和周树人是两位不同的现代作家。」——这是不折不扣的【事实性幻觉】。&lt;/p&gt;
&lt;p&gt;幻觉的精确定义是：模型生成了听起来合理、语法正确、但实际上不符合事实的内容。&lt;/p&gt;
&lt;p&gt;它不是 bug，是 LLM 概率生成机制的【固有特性】。&lt;/p&gt;
&lt;p&gt;要理解幻觉，先得承认一个事实：LLM 不是数据库，它是概率续写器。你给它一个问题，它做的不是「查询正确答案」，而是「猜测下一个最可能发生的内容」。这个区分是解决幻觉问题的认知基础。&lt;/p&gt;
&lt;h2 id="二幻觉的三大根源"&gt;二、幻觉的三大根源
&lt;/h2&gt;&lt;h3 id="第一层训练数据"&gt;第一层：训练数据
&lt;/h3&gt;&lt;p&gt;互联网语料本身就有错误、矛盾、过时信息。模型把它们全部「学进去」当作事实。比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;某个错误知识在网上流传甚广 → 模型学得深&lt;/li&gt;
&lt;li&gt;互相矛盾的信息并存（比如不同国家对同一历史事件的描述不同）→ 模型学到两种说法轮流出现&lt;/li&gt;
&lt;li&gt;训练截止日期之后的事件 → 模型一无所知，面对这类问题只能靠概率推断&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;训练数据的问题还包括「重复偏见」——如果某个错误信息出现了很多次（比如某个谣言被广泛传播），模型会认为它更可信。这是训练机制本身的副作用：语料出现频率高 → 权重被放大。&lt;/p&gt;
&lt;h3 id="第二层生成机制最本质"&gt;第二层：生成机制（最本质）
&lt;/h3&gt;&lt;p&gt;LLM 的工作方式是：给定前面的文本，按概率分布选下一个词。&lt;/p&gt;
&lt;p&gt;问题在于：概率最高 ≠ 事实正确。&lt;/p&gt;
&lt;p&gt;你问「鲁迅是谁的笔名」→ 正确答案「周树人」在概率分布中排名第一，模型答对。
你问一个模型从未见过的问题 → 概率分布中排名第一的，可能是一个【编造出来的、看起来最合理的答案】。&lt;/p&gt;
&lt;p&gt;模型的训练目标是「生成看起来最连贯、最像人话的文本」，不是「输出真实信息」。当它不知道怎么答的时候，它会「编造一个最合理的答案」，因为这是它的本职工作。&lt;/p&gt;
&lt;p&gt;把 Temperature 调到0也不能消除幻觉——概率最高的那条路径本身可能就是错的。Temperature 控制的是随机性，不是「知不知道」。模型不知道的时候，即使不随机，也会沿着最像真的那条路径走到一个错误答案。&lt;/p&gt;
&lt;h3 id="第三层对齐训练alignment"&gt;第三层：对齐训练（Alignment）
&lt;/h3&gt;&lt;p&gt;这是最容易被忽略的一层。SFT（监督微调）和 RLHF（基于人类反馈的强化学习）有一个隐藏的副作用：训练数据中的偏好是「自信地给出答案」比「诚实地说我不知道」得分更高。&lt;/p&gt;
&lt;p&gt;标注者通常更喜欢完整、自信的答案，而不是简短、不确定的回答。模型被这个奖励信号训练成了【不会拒绝回答】的角色。即使它不知道答案，也会尝试输出一大段说服力强但不保证正确的话，而不是说「抱歉，我不确定」。&lt;/p&gt;
&lt;h2 id="三幻觉的三类形态"&gt;三、幻觉的三类形态
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;例子&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;事实性幻觉&lt;/td&gt;
&lt;td&gt;编造不存在的事实&lt;/td&gt;
&lt;td&gt;「张爱玲获得过诺贝尔文学奖」&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;推理性幻觉&lt;/td&gt;
&lt;td&gt;逻辑链条断裂或自相矛盾&lt;/td&gt;
&lt;td&gt;「A&amp;gt;B，B&amp;gt;C，所以C&amp;gt;A」&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;上下文不一致&lt;/td&gt;
&lt;td&gt;违背用户给出的明确条件&lt;/td&gt;
&lt;td&gt;用户说「主角名叫李明」，模型后面说「张明的经历」&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;事实性幻觉最容易被发现——只要跟真实数据一对就知道。推理性幻觉更隐蔽，因为模型可能每一步看起来都有道理，但整体链条是断裂的。上下文不一致是在长对话里最恼人的——模型忘了你前面说过什么。&lt;/p&gt;
&lt;h2 id="四如何缓解幻觉三层组合拳"&gt;四、如何缓解幻觉？三层组合拳
&lt;/h2&gt;&lt;h3 id="训练层治本"&gt;训练层（治本）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;拒答能力训练：在 SFT 数据里专门加入「不知道就说不知道」的样本，让模型学会在必要时拒绝回答&lt;/li&gt;
&lt;li&gt;校准（Calibration）：让模型学会输出概率分数，表示对答案的信心度。用户可以根据置信度决定是否采信&lt;/li&gt;
&lt;li&gt;幻觉检测预训练：用外部知识库自动标注训练数据中的错误内容，在预训练阶段过滤低质来源&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="推理层治标"&gt;推理层（治标）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;分步推理（CoT）：让模型先分析再结论，错误推理更容易暴露&lt;/li&gt;
&lt;li&gt;低 Temperature + Top-P 采样：减少随机偏差，让输出更稳定&lt;/li&gt;
&lt;li&gt;Self-Consistency：对同一问题采样多次，投票取众数。错误答案不一定能稳定重复&lt;/li&gt;
&lt;li&gt;约束解码：限制输出只能在特定词汇表内（如只能输出数字 1/2/3），防止创造性胡编&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="系统层工程首选"&gt;系统层（工程首选）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;RAG（检索增强生成）：让模型「看着资料答」而不是「凭记忆答」——这是工业界最主流的解法&lt;/li&gt;
&lt;li&gt;答案后处理核查：用外部工具（如搜索引擎、数据库查询）验证关键事实&lt;/li&gt;
&lt;li&gt;强制带引用来源：要求模型在回答时标注信息来源，既方便追溯也方便人工核验&lt;/li&gt;
&lt;li&gt;知识蒸馏 + 事实编辑：在已有大模型基础上，用少量事实数据做局部参数修正&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="五致命认知误区"&gt;五、致命认知误区
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;误区1：「幻觉是数据问题，数据干净了就行了」&lt;/strong&gt;
→ 不完全是。即使训练数据100%正确，模型在没见过的问题上仍会依赖概率推断。LLM 的概率生成机制本身就是幻觉的土壤。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;误区2：「用 RAG 就能消除幻觉」&lt;/strong&gt;
→ RAG 只是把幻觉风险从「编造知识」转移到「编造引用」和「断章取义」。如果检索回来的内容本身就错了，或者模型把引用张冠李戴了，结果还是幻觉。RAG 降低幻觉率，但不是灵丹妙药。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;误区3：「越大越好的模型越不会幻觉」&lt;/strong&gt;
→ 规模增大确实能减少常识性幻觉（见过更多），但在小众知识领域幻觉反而可能更严重。大模型更「自信」，它对自己的错误回答也更有把握，更不容易说「我不知道」。&lt;/p&gt;
&lt;h2 id="六工程启示如何跟一个会撒谎的系统打交道"&gt;六、工程启示：如何跟一个会撒谎的系统打交道？
&lt;/h2&gt;&lt;p&gt;核心原则：系统级别的不信任校验机制。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;关键信息强制引用来源——回答必须带出处，出处可人工核验&lt;/li&gt;
&lt;li&gt;置信度透出——让用户知道模型对答案的不确定性，高置信采信、低置信核实&lt;/li&gt;
&lt;li&gt;关键领域人机配合——医疗、法律、金融等场景，模型只提供初步信息，最终判断由人类做&lt;/li&gt;
&lt;li&gt;设计可验证的交互——不是让模型直接给结论，而是让它推荐检索关键词，由用户确认后再查&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一句话总结：幻觉不可消灭，只能工程化收敛到「可接受风险」。&lt;/p&gt;
&lt;h2 id="七本章小结"&gt;七、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;幻觉是 LLM 概率生成机制的固有副产品，不是 bug&lt;/li&gt;
&lt;li&gt;根源分三层：训练数据污染、生成机制缺陷（概率最优≠事实）、对齐奖励鼓励「自信回答」&lt;/li&gt;
&lt;li&gt;三类幻觉：事实性、推理性、上下文不一致&lt;/li&gt;
&lt;li&gt;缓解需训练层+推理层+系统层三层组合拳，缺一不可&lt;/li&gt;
&lt;li&gt;最低成本的工程方案：RAG + 强制引用来源 + 置信度透出&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;如果模型知道自己不知道某件事，它应该怎么做最优？是「编造一个最接近的答案」还是「直接说不知道」？这取决于什么场景？&lt;/li&gt;
&lt;li&gt;为什么 LLM 在数学问题上也可能幻觉？代码领域幻觉和事实幻觉有什么不同？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>第1章：大语言模型到底是什么？从零开始的AI认知升级</title><link>https://blog.irudder.me/ai/knowledge-series/01-What-is-LLM.html</link><pubDate>Thu, 28 May 2026 00:00:00 +0800</pubDate><guid>https://blog.irudder.me/ai/knowledge-series/01-What-is-LLM.html</guid><description>&lt;h1 id="第1章大语言模型到底是什么从零开始的ai认知升级"&gt;第1章：大语言模型到底是什么？从零开始的AI认知升级
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;系列导读：这是「AI知识成长体系」系列的开篇。如果你刚接触大模型，本章帮你建立底层认知；如果你已有经验，建议从第3章「幻觉与可控性」开始，那里的工程视角同样值得回顾。&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一一句话定义"&gt;一、一句话定义
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;大语言模型（LLM, Large Language Model）&lt;strong&gt;是用海量文本语料预训练、参数规模达到百亿乃至万亿级别、基于&lt;/strong&gt;自回归&lt;/strong&gt;方式逐字生成文本的统一模型。&lt;/p&gt;
&lt;p&gt;它不是「一台能聊天的电脑」，也不是「一个搜索引擎」。最本质的理解是：&lt;strong&gt;它是一个概率续写器&lt;/strong&gt;——给定前n个词，预测第n+1个词的概率分布，然后挑一个词，继续往下预测。&lt;/p&gt;
&lt;h2 id="二一个核心类比"&gt;二、一个核心类比
&lt;/h2&gt;&lt;p&gt;想象你在玩「成语接龙」：我说「指鹿为马」，你说「马到成功」；我说「功」，你说「功成名就」……&lt;/p&gt;
&lt;p&gt;LLM 每天都在玩这个游戏，只是规模不一样：它接的不是几个字，是互联网上的几千亿个token。玩了几个月后，它发现自己不仅能填词，还能写诗、编程、做数学题。这就是 LLM 的根本工作方式——&lt;strong&gt;下一个 token 预测&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="三llm-vs-传统-nlp-的本质区别"&gt;三、LLM vs 传统 NLP 的本质区别
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;传统 NLP&lt;/th&gt;
&lt;th&gt;大语言模型&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;任务模式&lt;/td&gt;
&lt;td&gt;一任务一模型&lt;/td&gt;
&lt;td&gt;一模型万任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;实现方式&lt;/td&gt;
&lt;td&gt;流水线拆分：分词→词性标注→NER→下游任务&lt;/td&gt;
&lt;td&gt;端到端：输入文本，输出文本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;模型性质&lt;/td&gt;
&lt;td&gt;判别式（输出标签/概率）&lt;/td&gt;
&lt;td&gt;生成式（输出新文本）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;能力边界&lt;/td&gt;
&lt;td&gt;训练目标里有的才会&lt;/td&gt;
&lt;td&gt;规模够大时&lt;strong&gt;涌现&lt;/strong&gt;出新能力&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;迁移学习&lt;/td&gt;
&lt;td&gt;需要微调适配&lt;/td&gt;
&lt;td&gt;Prompt 即任务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="为什么说这是质变"&gt;为什么说这是「质变」？
&lt;/h3&gt;&lt;p&gt;传统 NLP 里，你要做情感分析，就训练一个情感分类器；做命名实体识别，就训一个 NER 模型。每个模型只会在训练数据里的「标签空间」内输出结果。&lt;/p&gt;
&lt;p&gt;LLM 不一样。它只学了一件事：&lt;strong&gt;预测下一个词&lt;/strong&gt;。但这个任务太极端了——互联网上的每一个句子都是一个训练样本。学会这个任务的过程中，它被迫理解了语法、语义、推理、常识、编程逻辑……所有能用语言表达的思维模式。&lt;/p&gt;
&lt;h3 id="涌现能力emergent-abilities"&gt;涌现能力（Emergent Abilities）
&lt;/h3&gt;&lt;p&gt;这是 LLM 最令人惊讶的特征。当模型规模突破某个阈值（通常是数十亿到百亿参数），会突然「涌现」出训练目标里没有显式教过的能力：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;上下文学习（In-Context Learning）&lt;/strong&gt;：给几个示例，模型就能学会新任务模式&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多步推理（Chain-of-Thought Reasoning）&lt;/strong&gt;：面对复杂问题能一步步拆解思考&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨语言迁移&lt;/strong&gt;：主要训练英语，却也能流畅地说中文、日语&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些能力在结构上没有变化，只是参数量变多了。就像水加热到100度突然沸腾——量变到了阈值，质变自然发生。&lt;/p&gt;
&lt;h2 id="四llm-的核心特性"&gt;四、LLM 的核心特性
&lt;/h2&gt;&lt;h3 id="1-知识冻结knowledge-cutoff"&gt;1. 知识冻结（Knowledge Cutoff）
&lt;/h3&gt;&lt;p&gt;LLM 的知识截止到训练数据的收集日期。GPT-4 训练数据到2024年初，之后的事它不知道。你问它2026年7月的股市走势，它会一本正经地编答案——这就是&lt;strong&gt;幻觉&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="2-没有真正的理解"&gt;2. 没有真正的「理解」
&lt;/h3&gt;&lt;p&gt;LLM 并不「理解」你说的每一句话。它只是在统计意义上学会了「哪些词组合在一起概率最高」。这带来了两个后果：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;它能做对数学题，但可能不理解数学意义&lt;/strong&gt;——因为训练数据里见过足够多的推导过程&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;它不会主动说「我不知道」&lt;/strong&gt;——因为训练目标要求它必须产出下一个词&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-上下文长度有限"&gt;3. 上下文长度有限
&lt;/h3&gt;&lt;p&gt;LLM 的「工作台」（context window）不是无限的。GPT-4o 是 128K token（约10万字），Claude 3.5 是 200K（约15万字），超过的部分会被遗忘。这意味着：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;长文档对话到后面会开始「掉线」&lt;/li&gt;
&lt;li&gt;RAG（检索增强生成）成为必修课&lt;/li&gt;
&lt;li&gt;任务拆解和记忆压缩是工程核心&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="五为什么说这是一个时代的开始"&gt;五、为什么说这是一个时代的开始？
&lt;/h2&gt;&lt;p&gt;LLM 的伟大之处，不在于它有多聪明，而在于&lt;strong&gt;它是第一个能用自然语言跟全世界沟通的通用接口&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;在它之前，你想让计算机做一件事，需要学编程语言、API 文档、数据库查询。现在你只需要说：「帮我写一个爬虫，抓取某网站的新闻标题。」&lt;/p&gt;
&lt;p&gt;它不完美，经常出错，但它开启了一个人机协作的新时代。它不是「替代人类」，而是「让人类用更自然的方式调用信息」。&lt;/p&gt;
&lt;h2 id="六本章小结"&gt;六、本章小结
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;LLM 本质是「下一个 token 预测」，参数规模带来的涌现效果是质变&lt;/li&gt;
&lt;li&gt;与传统 NLP 的根本区别在于「一模型万任务」和「涌现能力」&lt;/li&gt;
&lt;li&gt;LLM 有三大天生缺陷：知识冻结、没有真正的「理解」、上下文有限&lt;/li&gt;
&lt;li&gt;认识这些缺陷，才不会陷入「AI万能论」或「AI无用论」的两个极端&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思考题"&gt;思考题
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;如果 LLM 只是在做「概率续写」，为什么它能做对数学题？是「真正学会了」还是「模式匹配」？&lt;/li&gt;
&lt;li&gt;涌现能力的出现，对人工智能研究意味着什么？它是否暗示了规模是通往通用智能的路径之一？&lt;/li&gt;
&lt;/ol&gt;</description></item></channel></rss>