01 LLM、Agent、RAG、MCP、Skills 与 ReAct
该节点所属的教程路径尚未上线,仅能预览本节内容。
大模型基础
LLM 与自回归生成
输入法里打「今天天气真」,它自己蹦出个「好」。大模型干的是同一件事:根据已有上下文预测下一个 Token,追加进上下文后再预测下一个,直到结束,这叫自回归生成。
- Token:每一步补出来的文本碎片。
- 上下文窗口:一次调用能处理的总 Token 上限,系统提示词、历史消息、当前输入、输出预算都从里面扣。
- Temperature / Top-p:决定从候选里挑哪个。
- Max Tokens:最多允许模型补多少步。
Token
Token 是模型的阅读单位。人读中文按字、读英文按词,模型两样都不按:它用一套拆字规则(Tokenizer)把文本切成大小不等的碎片。
按字切,词表小但序列长;按词切,中文词组太多,词表会炸。实际用的是折中方案,也就是子词切分(BPE、Unigram):高频词整体保留,低频词拆成更小的块。所以 Token 不严格等于一个字或一个词,英文一个单词可能拆成几个 Token,中文一个词也可能拆成几个。容量规划靠经验估算,精确计费看 API 返回的 usage。例:「你好,我是小 G。」通常会切成 5 个 Token,怎么切由供应商的 Tokenizer 决定,同一段文本在不同厂商那里序列可能不同。
上下文窗口
上下文窗口是模型的工作记忆,决定它此刻能处理多少 Token:多轮对话能聊多久不忘前文、单次能塞多大的文档或代码库,都由它决定。标称「支持 128K/200K/1M」说的是一次调用的总量,多数模型把输入输出算在一起,也有供应商(比如 Gemini)给输入输出分别设限。
窗口里很大一块被隐形成本吃掉:System Prompt、多轮历史、RAG 片段、工具 Schema、格式开销,还有模型自己的输出。真正留给业务内容的空间比标称上限小不少。
采样参数
每一步模型都会给候选 Token 打分(logits),分越高说明它越觉得这个词该出现在这里。原始分不是概率,过一遍 softmax 才得到分布,再按分布抽签,解码参数就作用在这个过程里:
- Temperature 调整分布形状,让高分项更突出或者让各选项更平均。
- Top-p / Top-k 砍掉不靠谱的候选,缩小抽签池;Penalty 系列给出现过的词降分,防止复读。
Prompt
Prompt 是喂给模型的指令。模型的理解和指令跟随都依赖输入,边界不清就容易偏题甚至编造,所以 Prompt 的作用是缩小搜索范围:越模糊越容易乱猜,越结构化输出越可控。写得好不好不看长度,看有没有把任务说清楚。合格的 Prompt 一般交代四件事:
- Role:用哪个领域的声音,「你是一位 10 年经验的 Java 架构师」。
- Task:要做什么,「请评审以下代码的性能问题」。
- Context:相关背景,「线上 QPS 2000,响应时间超 500ms」。
- Format:输出长什么样,「输出 JSON,包含 bottleneck、solution 两个字段」。
结构化输出
常见 Prompt:判断用户反馈属于哪类工单,返回 JSON。模型返回的结果看着没问题,但也只是看着。接进后端后你要的是一份稳定的契约:category 只能是四个枚举值之一,priority 只能是 LOW/MEDIUM/HIGH,confidence 是 0 到 1 的小数,reason 能不能为空、信息不足时该返回什么。自然语言 Prompt 守不住这些边界。
三个常被混着说的概念不在同一层:JSON Mode 是输出模式,约束模型返回合法 JSON;JSON Schema 是结构描述规范,定义字段、类型、必填、枚举;Structured Outputs 接收 Schema,在生成阶段尽量或严格贴合它。真正让模型按契约生成的是 Structured Outputs 和 Function Calling,JSON Schema 只是契约格式。
Function Calling / Tool Calling
这名字容易误导新人,好像模型真去执行了你的 Java 方法。并没有:它只是根据用户问题和工具描述生成一个结构化的调用意图,真正执行工具的是业务服务、Agent Runtime 或 MCP Host。
典型链路:注册工具定义(工具名、用途、参数 Schema)→ 用户请求「帮我查一下订单 1029384756 到哪了」→ 模型选出 query_order 并给出参数 {"orderId": "1029384756"} → 业务侧校验类型、权限、幂等键后调用订单系统 → 结果连同 tool_use_id 原样回填(Anthropic 要求严格匹配,Gemini 3 也给每个 functionCall 生成唯一 id,不带回去会导致并行调用结果错配)→ 模型把结果转成人话。
Agent
什么是 Agent
翻一下 LangChain 的 Agent 源码会发现核心就是个 while 循环。Agent 是能感知环境、做决策、执行动作的软件系统:LLM 负责理解和决策,工具负责执行,记忆负责保存上下文和经验。它和聊天机器人的差别在于会持续观察、判断、执行,直到任务结束。公式是 Agent = LLM + Planning + Memory + Tools。
- 推理与规划:用 LLM 分析当前状态、拆目标、定下一步,CoT 提示能让模型逐步推理。
- 记忆分两层:短期是上下文历史,保证对话连续;长期是外部知识库,比如向量库或知识图谱。短期管「刚才说过什么」,长期管「过去积累了什么」。
- 工具:让模型能查数据、调 API、读文件、执行代码。没有工具,它大多只能停在「建议你怎么做」。
工具返回结果后放回上下文,再进入下一轮推理,这个反馈闭环就是 Observation,也是循环能转下去的关键。
Agent Loop
每一轮干三件事:LLM 推理、调用工具、把结果写回上下文,循环到任务完成或触发停止条件。初始化时加载 System Prompt、工具列表和用户请求;迭代时读上下文、决定调不调工具、执行工具、把结果追加进上下文;不再调工具就退出;另外设最大迭代轮次(一般 10 到 20 轮)或 Token 阈值兜底,防死循环。
难点不在 while 本身,而在上下文管理:任务跑久了上下文越来越长,关键信息被稀释,模型就容易跑偏,这正是 Context Engineering 要解决的问题。LangChain、LlamaIndex、Spring AI 都对 Loop 做了封装,底层思路差不多。
ReAct
ReAct 是 Reasoning + Acting,Shunyu Yao 等人在 2022 年的论文里提出。思路很直观:先推理一步,拿到环境反馈,再推理下一步,交替进行。模型缺实时信息又容易幻觉,ReAct 让它走一步看一步。落地需要历史上下文、实时环境输入、推理模块、工具集与技能库、反馈观察机制配合。好处是减少幻觉、复杂任务成功率更高、每一步为什么这么做也解释得清;代价是多轮迭代增加延迟,也很依赖工具和 Skills 的质量。
Plan-and-Execute
LangChain 团队 2023 年提出:先让 LLM 制定全局分步计划,再由执行器按步骤完成。适合步骤多、依赖明确的长期任务,比 ReAct 更不容易在长任务里迷路。缺点是计划一定下来,动态调整和容错就弱,更像静态工作流。实际项目里两种可以组合:先用 CoT 生成全局步骤,每个步骤内部嵌一个 ReAct 子循环。
Workflow、Graph 与 Loop
很多人一听 Agent 就默认该让模型自己规划、自己调工具、自己跑完全程,听着智能,落地不一定稳。纯 Agent 里 LLM 是决策者,每一步怎么走都靠模型推理;AI 工作流里 LLM 只是流程里的一个节点,骨架(步骤顺序、条件跳转、失败重试)提前设计好,控制权在图结构里。Agentic Workflows 是两者混着用:全局用 Workflow 管结构,在不确定的节点里嵌 Agent 子循环。
工作流的数据结构是有向图:Node 负责执行,Edge 负责控制流,State 在节点间共享上下文。
Context Engineering
Agent 做不好,很多时候是上下文太乱,而不是模型能力不足。Context Engineering 就是在有限的 Token 窗口里把最有用的信息喂给模型,把噪声挡在外面。它比 Prompt Engineering 管得宽:规则、记忆、工具描述、会话状态、外部观察、Token 预算都归它管。
Memory
短期记忆是 Session 级的,服务当前任务;长期记忆跨 Session,沉淀用户偏好、历史决策和过往经验,两者在物理和逻辑上都该分开。按功能分三类:
| 功能类型 | 解决的问题 | 存储内容 |
|---|---|---|
| 事实记忆 | 智能体知道什么 | 用户偏好、环境状态、显式事实 |
| 经验记忆 | 智能体如何改进 | 过往轨迹、成败教训、策略知识 |
| 工作记忆 | 智能体当前在想什么 | 当前推理上下文、任务进展 |
长期记忆和 RAG 都用向量库和语义检索,但服务对象不同:RAG 检索外部知识源(公司规章、产品文档、实时库查询),长期记忆管的是与特定用户交互中沉淀的个性化经验。
MCP
MCP 全称 Model Context Protocol,中文叫模型上下文协议。拆开看就清楚:Model 面向大模型应用,Context 把外部上下文、工具和数据源带给模型,Protocol 用一套标准把交互方式定下来。
别把它理解成「给模型加插件」。准确说,MCP 是 Client 和 Server 之间的通信协议:Host 承载用户交互和模型调用,Client 负责和 Server 说话,Server 把能力暴露出来。它和 Function Calling、Agent、Skills 经常一起出现但不在同一层:Function Calling 解决模型怎么表达想调工具,MCP 解决工具从哪来、怎么被连接,Agent 关注任务怎么一步步做完。
Skills
Skill 是一份可被 Agent 发现、按需加载的任务说明,把某类任务的经验、约束和执行顺序沉淀下来,需要时再读。接口返回格式怎么统一、日志字段怎么打、慢 SQL 怎么查、Review 先看架构还是先看异常处理,以前要么散在文档里要么靠人反复提醒,现在可以集中写进 SKILL.md。
它不是 Prompt、MCP、Function Calling 的替代品,几个东西不在同一层。放进一条执行链路看就清楚:用户说「帮我分析这份报表」是 Prompt;模型判断要调 read_file 并生成结构化参数是 Function Calling;read_file 的能力如果来自 MCP Server,MCP 管的是连接和协议;而「先看字段含义、再看异常值、最后给业务结论」才是 Skill 该放的内容。
Harness Engineering
一个粗暴但好记的说法:Agent = Model + Harness。你不是模型,那你做的大概率就是 Harness。
Harness 指模型之外的整套系统:系统提示词、工具调用、文件系统、沙箱、编排逻辑、反馈回路、约束机制。模型只提供推理和生成,Harness 把状态、工具、反馈、执行环境串起来,Agent 才能真正干活。
Prompt Engineering、Context Engineering、Harness Engineering 不在同一层,它们一层套一层:
| 层级 | 解决的问题 | 关注点 |
|---|---|---|
| Prompt Engineering | 怎么把指令说清楚 | 减少局部歧义 |
| Context Engineering | 该给 Agent 看什么 | 在合适时机提供正确且必要的信息 |
| Harness Engineering | 系统怎么持续执行、纠偏、观测和恢复 | 长链路任务的持续正确与故障恢复 |
Loop Engineering
一句话:围绕 Agent 设计可持续运行的反馈循环,让它在明确的目标、工具、上下文、验证信号和停止条件下反复行动,直到任务完成、失败或需要人工接管。落到工程上看这些点:
- 触发:谁启动这轮任务?手动命令、定时任务、CI 失败、PR 创建,还是消息事件。
- 目标:什么状态算完成?测试全绿、覆盖率达标、截图对齐设计稿,还是只出待确认的草稿。
- 上下文与行动:每轮看哪些文件、规则和历史状态;能改代码、跑测试、读日志、发 PR,还是只能给建议。
- 观察与状态:测试输出、lint、截图、审查评论都算验证信号;试过什么、失败在哪要写到外部文件,不能只靠当前对话记。
- 停止:什么时候退出、什么时候转人工、什么时候因为预算或轮次耗尽直接停。
Agent Loop 和 ReAct 都是这个思路,本身不新鲜,难的是每一条都落到实处。
RAG
什么是 RAG
RAG(检索增强生成)把信息检索和大模型绑在一起用:先从知识库检索出和问题相关的片段,连同原始问题一起喂给 LLM,让模型基于检索内容回答,而不是只靠训练时记住的东西。它补的是大模型的三个短板:
- 知识时效性:预训练知识停在训练数据截止时间,之后的新事件、新政策模型默认不知道,RAG 动态检索外部知识源补上。
- 私有数据:企业内部文档、客户数据不可能让公开模型随便访问,RAG 只提取相关片段。
- 幻觉:给出参考文本能让模型尽量基于证据回答,但别指望彻底消除——检索错误、上下文噪声、引用错配都会导致错误答案,生产环境通常还要配引用校验、答案评估、拒答机制和人工反馈闭环。
工作原理
链路分两个阶段:离线索引把原始文档处理成可检索的数据结构,在线阶段在用户提问时做查询理解、检索召回、上下文构建和答案生成。索引阶段是:输入文档(文本、PDF、网页、数据库记录)→ 清理噪声 → 补充元数据(时间戳、分类标签)→ Chunking 切分 → Embedding 向量化 → 存入向量库或索引系统,比如 Milvus、pgvector、Elasticsearch、Faiss。Chunking 是关键一步:要兼顾语义完整性、Embedding 模型的输入长度、生成模型的上下文窗口和召回粒度,块太大引入噪声,太小丢上下文。
Embedding
Embedding 把文本变成一串数字,更准确说是映射到高维稠密向量空间,让语义接近的文本距离更近。「如何申请退款」「退款流程是什么」「订单怎么取消并退钱」字面不同但语义接近,好的模型会把它们映射到相近位置,向量检索才能把相关 Chunk 捞出来。
常见维度有 768、1024、1536、3072。维度是模型设计和训练方式的一部分,不能脱离模型说「越高效果越好」,维度高通常意味着存储、索引和相似度计算成本更高。OpenAI 的 text-embedding-3-small 默认 1536 维,text-embedding-3-large 默认 3072 维,也支持用 dimensions 参数降维。
向量检索与向量数据库
基本流程:文档切成 Chunk,每个 Chunk 转成向量,连同原文和元数据写进向量库;用户提问时问题也转成查询向量,检索出最相似的 Top-K,放进 Prompt 交给 LLM 生成答案。向量检索只是 RAG 的一种实现,BM25、SQL、知识图谱、搜索 API 同样能提供外部证据。几千条向量的 demo 放内存暴力搜就行,真实系统很快到百万级,向量数据库要解决的是索引、过滤、更新、扩展这些工程问题。
文档处理
从上传到进向量库至少六个环节,每个都有坑:上传时格式伪造、大小超限、编码混乱会让解析器崩溃或静默失败;扩展名和真实 MIME 不符会选错解析器;Layout 解析要处理 PDF 多栏、合并单元格、页眉页脚,否则结构丢失、上下文错位;清洗漏掉乱码、重复空行、目录残留,噪声就进索引,Embedding 跟着失真;Chunking 出现语义截断或块大小失衡,召回不准;Metadata 没保存来源、页码、版本、权限,后面无法过滤也无法引用;入库时向量维度不一致或 Token 超限,直接检索失败。
数据在这一步就坏掉的话,后面换 embedding 模型只会让损坏更稳定;质量校验也别只在入库后做,Chunking 阶段采样校验能提前发现问题。
切分策略
文档本身有清晰结构时,按结构切通常更合适。NVIDIA 的测试里 Page-Level Chunking 在金融报告和法律文档上表现最好,平均准确率 0.648,方差也最低,这类材料的页面边界往往承载章节或版式语义。但也别迷信:相对 Token 切分只领先 0.3 到 4.5 个百分点,在 FinanceBench 上 1024-token 切分反而更好。查询类型也影响选择:事实型查询适合 256-512 Token 的小块,分析型适合 1024+ Token 或页面级。
小块召回准但上下文残缺,大块保留完整但噪声大,这个矛盾迟早会撞上。Parent-Child Chunk 的解法是先用 300 Token 左右的小块做向量检索,每个小块挂到一个 1200 Token 的父段落上,检索时先命中小块,再把父段落放进上下文,精度和上下文都保住。
Hybrid Search
向量检索擅长语义相似,BM25 擅长精确词匹配,两者互补。「如何取消订阅」这类查询,向量能匹配到「关闭自动续费」,BM25 可能匹配不到;而「错误码 E1027」「ABX-4421 型号参数」这类查询,纯向量容易召回泛化故障或相似型号,必须靠关键词召回。常见做法是两路召回后融合:向量返回语义候选,BM25 或稀疏向量返回关键词候选,用 RRF 或归一化加权分数合并,去重后进 Rerank。RRF 的好处是不用强行比较 BM25 分数和向量余弦分数,按排名位置融合,调参负担更低。
但也别神化它:文档高度结构化、关键词很少时增益有限;查询里大量出现错误码、型号、配置项时,纯向量很容易翻车。
Query Rewrite
用户的问题不是为检索系统写的。「这个报错咋整」「钱能退吗」,对人来说有上下文,对检索系统很模糊。Query Rewrite 要在不改变意图的前提下把问题改写成更适合召回的表达,常见策略有规范化改写(「钱能退吗」→「退款政策、退款条件、退款流程」)、Multi-Query(同时检索「取消订阅」「关闭自动续费」)、Query Decomposition(拆开含多个子问题的问题)、HyDE(先生成假设答案,再用它检索真实文档)、Self-Query(从问题里提取过滤条件)。
有个坑:改写必须保留原始问题,别只用改写后的查询。让原始 query 和改写 query 一起召回再融合,否则改写模型一旦理解错意图,后面召回全偏。
Rerank
向量检索是双塔思路,query 和 document 分别编码再算距离,快但不够细。Rerank 用 Cross-Encoder 或专用重排模型把 query 和候选放一起打分,慢一些,但更能判断这段文本是不是真能回答这个问题。比如问「线程池为什么会触发拒绝策略」,向量召回可能先给出参数说明和枚举列表,真正解释触发条件的片段排在后面,Rerank 的价值就是把它顶上来。
推荐链路:Metadata 预过滤 → Hybrid Search 粗召回 30 到 100 条 → 去重和相邻片段合并 → Rerank 选出 5 到 10 条 → 上下文压缩后进 Prompt。
GraphRAG
GraphRAG 把图结构用于检索增强:把文档里的实体、关系和结构化上下文显式建模,查询时沿图关系收集证据。重点不是「用了图数据库」,而是检索对象变了:传统向量 RAG 检索文本 Chunk,GraphRAG 还能检索节点、边、图路径和原文证据。
| 维度 | 传统向量 RAG | GraphRAG |
|---|---|---|
| 检索对象 | 文本 Chunk | 实体、关系、路径、社区摘要、原文片段 |
| 核心能力 | 语义相似度召回 | 关系推理、图遍历、全局主题聚合 |
| 数据结构 | 向量索引为主 | 知识图谱 + 向量索引 + 全文索引 |
| 适合问题 | 局部事实问答、文档片段解释 | 多跳关系问答、跨文档归纳、复杂业务分析 |