从LLM到Agent,从RAG到MCP,学习自主智能体的一份实战笔记
小白学习AI Agent,这篇文章是我这段时间学习相关概念的笔记总结,涵盖了LLM底层机制、Agent核心架构、MCP协议和RAG原理,希望能帮你建立起对Agent技术的整体认知。
一、重新理解LLM:Agent的“大脑”是如何工作的?
在深入Agent之前,我们有必要先搞清楚大语言模型(LLM)的运行机制——因为Agent的所有智能行为,归根结底都是LLM在驱动。
1.1 一次完整的LLM推理流程
用户输入 → Tokenizer切分(字符→Token序列) → 构建上下文窗口(Prompt + 历史 + RAG片段 + 工具Schema) → 模型推理(Transformer + 自注意力) → 输出logits(每个Token的原始分数) → 采样策略(Temperature / Top-p / Top-k) → 生成下一个Token → 重复直到遇到EOS或达到最大长度 → 结构化输出解析(JSON/XML等) → 返回给业务方
1.2 Token:计费与上下文的基本单位
Token是LLM处理文本的最小单元,不同字符类型消耗的Token数量不同(以DeepSeek为例):
1个英文字符 ≈ 0.3 Token
1个中文字符 ≈ 0.6 Token
图片会被“视觉编码器”转换成一批Token,分辨率越高,Token越多
💡 实践经验:调用API时,可以用tiktoken(OpenAI)或模型厂商提供的工具预先计算Token数,避免超限。
1.3 上下文窗口:LLM的“工作记忆”
上下文窗口决定了模型一次能“记住”多少信息(以Token计)。但注意:窗口内的内容并非平等对待:
注意力衰减:Transformer对窗口中间位置的信息召回率明显低于开头和结尾
实际占用分布(典型场景):
System Prompt:10-30%
User Prompt:5-15%
多轮对话历史:20-40%
RAG检索片段:20-40%
工具调用Schema:5-10%
模型输出:10-20%
1.4 上下文溢出时的“症状”
当输入Token超过模型最大窗口时,会出现:
早期约束被忽略:窗口开头的指令(如“你必须用JSON格式回答”)失效
回答漂移:生成内容逐渐偏离主题
RAG失效:检索到的相关片段落在注意力盲区
成本与延迟激增:处理超长上下文极不经济
✅ 解决方案:使用Prompt Caching——将不变的部分(如System Prompt)放在前面,短时间内重复请求可命中缓存,降低90%+成本。
1.5 采样参数:控制输出的“性格”
| 参数 | 作用 | 效果 |
| Temperature | 调整概率分布的形状 | T=0 贪婪解码(确定);T>1 更随机 |
| Top-p(nucleus sampling) | 保留概率累加≥p的候选Token | 常用0.9-0.95,自动适应分布 |
| Top-k | 只保留概率最高的k个候选 | 通常与Top-p配合使用 |
🎯 组合建议:
结构化输出(JSON/SQL):T=0(贪婪解码)或 T=0.1 + Top-p=0.9
分析报告/摘要:T=0.3 + Top-p=0.9(稳定中带一点措辞变化)
创意写作/对话:T=0.8 + Top-p=0.95(多样性高但不过分离谱)
⚠️ 注意:贪婪解码虽然最稳定,但容易陷入重复循环(比如反复输出同一段话),需要配合重复惩罚参数。
1.6 流式输出(Streaming)
边生成边返回,显著降低首字延迟(TTFT)。但注意:如果输出是结构化格式(如JSON),必须等到流结束再解析,或使用流式JSON解析器(如ijson)。
二、AI Agent:让LLM“长出手脚”
2.1 Agent的定义与经典公式
AI Agent 是一种能感知环境、进行决策并执行动作的自主软件系统。它以LLM为大脑,代表用户自动化完成复杂任务。
经典公式:
Agent = LLM + Planning + Memory + Tools
2.2 Agent Loop:所有范式的运行引擎
所有Agent框架底层都跑着同一个while循环:
while not task_complete: # 1. LLM推理:根据当前状态决定下一步动作 action = llm.infer(context + memory) # 2. 如果是工具调用,执行并获取观察结果 if action.type == "tool_call": observation = execute_tool(action) else: observation = action.direct_output() # 3. 更新上下文与记忆 context.append(action, observation) memory.update(action, observation) # 4. 检查终止条件(完成/超时/错误)2.3 Agent框架的三层能力
LLM Call层:底层API管理,抹平厂商差异,处理重试/退避/流式/截断
Tools Call层:解决LLM如何调用外部函数的问题(函数描述、参数校验、结果返回)
Context Engineering层:管理传递给LLM的Prompt集合(动态组装、按需加载)
2.4 Skills:将工具组合升级为“技能”
当多个原子工具在特定场景下被反复组合调用时,可以将这个调用序列封装为一个Skill,对外暴露为单一接口。
Agent Skills 的典型实现:以SKILL.md文件为核心的自然语言指令集,包含:
YAML front-matter(名称、描述、版本等元数据)
详细自然语言指令(步骤、注意事项、示例)
🚀 延迟加载(Lazy Loading):启动时只读front-matter做发现(不占上下文),LLM决定调用时才动态加载完整内容注入上下文。这种设计让Agent可以拥有成百上千个技能而不撑爆窗口。
2.5 ReAct模式:思考与行动的交替
ReAct = Reasoning + Acting,是目前最具代表性的Agent范式。它让Agent像人类一样:
先思考(Reasoning):当前状态是什么?下一步该做什么?
再行动(Acting):调用工具或输出结果
观察反馈(Observing):工具返回了什么?环境发生了什么变化?
循环迭代,直到任务完成
💡 典型应用:信息检索、调试排错、多跳问答。
2.6 Plan-and-Execute:先规划后执行
与ReAct的“边想边做”不同,Plan-and-Execute模式让LLM先担任规划者,制定全局分步计划,再由执行器按步骤完成。
优势:
减少不必要的LLM调用次数
更易于调试和人工干预(修改计划后重试)
适合有明确步骤的复杂任务
2.7 Reflection:让Agent学会自我纠错
Reflection 赋予Agent通过自然语言反馈自我优化的能力,无需调整模型权重(零训练成本)。
三种主流实现:
Reflexion:任务失败后生成反思结论,存入记忆供下次尝试
Self-Refine:生成初稿 → 自我批评(“内容不够具体”)→ 修订 → 循环至满足标准
CRITIC:引入外部工具(如代码执行器、事实核查API)验证输出,再基于结果修正
🔥 进阶组合:Plan + ReAct + Reflection —— 规划阶段用CoT生成步骤,执行阶段嵌入ReAct子循环,每轮观察后不仅更新计划,还进行显式自我反思,形成自适应Agent。
2.8 Multi-Agent:团队分工协作
多个独立Agent通过协作完成复杂任务,每个Agent专注于特定角色:
编排者(Orchestrator):负责任务拆解、分发、结果聚合
子Agent(Sub-agents):各自擅长不同领域(代码执行、信息检索、内容生成、数据校验)
主流架构:Orchestrator-Subagent模式,编排Agent负责任务规划,多个子Agent并行或串行执行,最终由编排Agent输出综合结果。
A2A(Agent-to-Agent)协议:专门为AI智能体间高效、确定性协作而设计的通信规范(基于JSON-RPC 2.0)。
2.9 Agentic Workflows:四大核心设计模式
Andrew Ng提出的四大模式:
Reflection(反思)
Tool Use(工具使用)
Planning(规划)
Multi-Agent Collaboration(多智能体协作)
不要仅仅把LLM当作“一次性回答生成器”,而是围绕它设计一套工作流。
三、MCP(Model Context Protocol):工具的标准化接入
MCP是Anthropic提出的开放协议,旨在统一LLM与外部工具的交互方式。
3.1 核心特性
通信协议:JSON-RPC 2.0
四大核心能力:
Resources(只读数据,如文件、数据库记录)
Tools(可执行动作,如发邮件、查天气)
Prompts(预设指令模板)
Sampling(请求LLM进行推理,实现嵌套调用)
3.2 四层架构
Host(宿主应用,如Claude Desktop) → Client(MCP客户端) → Server(MCP服务器,一个Server可暴露多个能力) → Data Source(本地文件、API、数据库等)
一对多连接:一个Host可连接多个Server
模型无感知:LLM只需要知道标准化的函数描述,不关心底层实现
3.3 传输方式
stdio:本地进程通信(启动子进程,通过标准输入输出交互)
HTTP/SSE:远程通信,支持服务端推送
3.4 MCP让LLM能够做什么?
访问本地文件系统 → 构建个人知识库
查询和操作数据库(MySQL、Elasticsearch、Redis)
调用外部API(天气、地图、GitHub、Slack)
控制浏览器和自动化工具(Playwright、Puppeteer)
执行数据分析和可视化(Python、pandas、matplotlib)
📌 实战建议:如果你正在开发Agent,优先考虑实现MCP Server,这样你的工具可以被任何支持MCP的宿主应用调用,实现“一次编写,到处集成”。
四、RAG(检索增强生成):对抗幻觉的利器
4.1 核心思想
在让LLM回答问题之前,先从知识库中检索相关上下文,与问题一并提供给LLM。
解决的问题:
✅ 知识时效性(对抗“知识截止日期”)
✅ 私有数据接入(企业文档、内部Wiki)
✅ 回答准确性与可追溯性(对抗幻觉,提供引用来源)
4.2 RAG全流程
索引阶段(离线/定期执行)
原始文档 → 文档清理(去HTML标签、特殊字符) → 文档增强(添加元数据、摘要) → 文档拆分(按段落/语义切块,保持重叠) → 向量化表示(Embedding模型) → 存入向量数据库(Pinecone、Chroma、Milvus、FAISS)
检索阶段(在线/每次请求)
用户问题 → 问题向量化 → 向量检索(Top-K相似度) → 获取相关片段 → 构建增强Prompt(问题 + 片段 + 指令) → LLM生成回答 → 可选:结果反馈(点击率、点赞)用于优化检索
4.3 关键参数调优
| 参数 | 作用 | 推荐范围 |
| Chunk Size | 每个片段的大小 | 256-512 tokens |
| Overlap | 相邻片段重叠大小 | 10-20% of chunk size |
| Top-K | 检索返回的片段数 | 3月10日 |
| Similarity Threshold | 最低相似度阈值 | 0.7-0.8 |
4.4 进阶RAG技术
HyDE:用LLM先生成一个假设答案,再用假设答案去检索
Self-RAG:检索后让LLM自我评估片段相关性,决定是否重新检索
RAPTOR:构建层次化摘要树,先检索摘要再深入细节
Graph RAG:引入知识图谱,利用实体关系进行检索
4.5 RAG常见坑点与优化
| 问题 | 优化方案 |
| 检索到的片段不相关 | 调高相似度阈值,或使用重排序(Re-ranking)模型 |
| 片段太多撑爆上下文 | 压缩片段(LLM总结)或只保留最相关的Top-3 |
| 回答中幻觉依然存在 | 在Prompt中要求“只基于提供的内容回答,不确定就说不知道” |
| 检索延迟高 | 缓存热门查询的检索结果,或使用近似最近邻索引(HNSW) |
写在最后:小白第一次写博客,中间有些内容做的可能不太好,但是大家有什么好的建议我会很认真的去改正的。