一、ReactAgent
ReAct(Reasoning + Acting)是一种将推理和行动相结合的 Agent 范式。在这个范式中,Agent 会:
- 思考(Reasoning):分析当前情况,决定下一步该做什么
- 行动(Acting):执行工具调用或生成最终答案
- 观察(Observation):接收工具执行的结果
- 迭代:基于观察结果继续思考和行动,直到完成任务
1、工作原理
Spring AI Alibaba 中的 ReactAgent 基于 Graph 运行时构建。Graph 由节点(steps)和边(connections)组成,定义了 Agent 如何处理信息。Agent 在这个 Graph 中移动,执行如下节点:
- Model Node (模型节点):调用 LLM 进行推理和决策
- Tool Node (工具节点):执行工具调用
- 工具赋予 Agent 执行操作的能力,支持顺序执行、并行调用、动态选择和错误处理。
- Hook Nodes (钩子节点):在关键位置插入自定义逻辑
2、Tools
Tools 是 agents 调用来执行操作的组件。Tools 封装了一个可调用的函数及其输入模式。我们可以把工具定义传递给兼容的 models,允许模型决定是否调用工具以及使用什么参数。在这些场景中,工具调用使模型能够生成符合指定输入模式的请求。
Tool calling(也称为 function calling)是 AI 应用程序中的常见模式,允许 model 与一组 API 或 tools 交互,增强其能力。
尽管我们通常将 tool calling 称为 model 能力,但实际上由客户端应用程序提供 tool calling 逻辑。Model 只能请求 tool call 并提供输入参数,而应用程序负责从输入参数执行 tool call 并返回结果。Model 永远无法访问作为 tools 提供的任何 API,这是一个关键的安全考虑。
二、Harness Engineering
Harness Engineering的价值在于将模型的潜力转化为稳定、可预测的生产力。其核心组件构成了智能体(Agent)可靠运行的基石
Agent = Model + Harness
1、从 Prompt 到 Harness
- 提示词工程(Prompt Engineering):解决"如何与模型有效对话"的问题,通过设计优质提示模板来优化单次输出质量。
- 上下文工程(Context Engineering):解决"模型应该看到什么信息"的问题,通过RAG等技术为模型提供实时、准确的外部知识,以应对"幻觉"和知识滞后。
- 驾驭工程(Harness Engineering):解决"如何让AI在真实环境中可靠、自主地工作"的问题,它把大模型视为一个强大但不可控的"引擎"或"野马",核心任务是在其外部构建一套完整的"马具"系统进行约束和引导。
2、核心思想
- 给目录而不是整本说明书
不要尝试用一个巨大的 AGENTS.md 文件来指导AI来完成代码生成,因为它会挤占上下文、不能体现规则的重要等级、导致规则难以维护
正确做法是将 AGENTS.md 控制在约 100 行,仅作为索引目录,AI需要时再根据目录找到深层知识,也就是我们所说的渐进式披露(PS:SKILL不就是这个样子吗,同样的道理不要写过长的SKILL.md)。 - 规则要沉淀到仓库
代码仓库是 AI 唯一能看到的世界,AI没有办法看到人类大脑中的想法,也无法知道编码环境之外的任何内容。因此我们平时所有的设计决策、架构约定、团队共识都必须以版本化的 Markdown、代码或可执行计划的形式提交到仓库,否则AI会像一个迟到三个月入职的新员工,对这些信息一无所知。 - 务必要有架构约束
仅靠一个文本或者Prompt没有办法约束AI生成完全符合要求的代码,AI只有在架构确定的环境中效率才是最高的。我们可以通过脚本、流水线等校验生成的代码是否满足架构约束,防止出现架构漂移。需要注意的是,在规则中应该明确哪些地方需要限制,哪些地方不需要限制,比如生成的代码必须分为gateway、domain、dao三层,至于某一层或者某一块的具体实现,允许AI自由发挥。 - 构建AI可观测的系统
AI的代码生产效率远远高于人类,这时候人的评审反而成了效率的瓶颈,因此最好的方式是AI可以自己发现错误、修复错误、验证修复。例如将日志、监控等信息通过文件、MCP等方式暴漏给AI,让AI可以自己闭环掉开发------测试------修复。 - 等待成本高于纠错成本
这里一条我是存疑的,因为在很多场景,比如金融支付业务,安全稳定比快更重要。文中提到PR 生命周期应尽量短,不要因为偶发性失败而阻塞,因为AI的代码产出速度远远超出人类的PR速度,纠错成本低,等待成本高。 - 让AI自动清理垃圾代码
AI生成新代码时会参考已有代码,因此一次坏的实现会被多次复制,架构可能快速漂移。这个如果靠人来手动处理会耗费极大的时间和精力,因此需要将"黄金原则"编码到仓库中,并运行后台 Codex 任务定期扫描偏差、发起重构 PR------持续小步迭代还债远好过等到累积到一个大债务再去解决。 - 人类的建议要沉淀到仓库中
代码审查中的评论、重构 PR 和用户反馈中体现出了人类对代码实现的要求,这些信息如果只停留在口头或聊天记录中就无法影响未来AI的输出,因此必须将这些信息提取为规则,写到文档中或者编码进工具,才能让人类的要求持续的约束AI,而不是随着时间流逝而消失。
三、MCP
模型上下文协议(Model Context Protocol,MCP),是由Anthropic推出的开源协议,旨在实现大语言模型与外部数据源和工具的集成,用来在大模型和数据源之间建立安全双向的连接。
1、核心组件
MCP 采用客户端 - 服务器架构,包含三个核心组件协同工作:
- MCP 主机(Host):发起请求的 AI 应用程序,如 Claude Desktop、Cursor、VS Code 等 AI 工具,为用户提供与人工智能模型互动的平台 。
- MCP 客户端(Client):运行于主机内部,负责与 MCP 服务器建立通信,充当宿主与外部资源之间的桥梁,确保信息实时性与一致性 。
- MCP 服务器(Server):提供后端服务支撑,暴露特定功能接口和数据访问能力,分为本地数据源(文件、数据库)和远程服务源(API、云服务)。
2、协议格式
MCP 协议使用 JSON-RPC 2.0 作为消息传输格式,包含Request、Response、Notification三种类型的 JSON-RPC 消息
Request示例:
{
"jsonrpc": "2.0",
"id": 1, // 请求 ID(数字或字符串)
"method": "string", // 方法名
"params": {} // 可选,参数对象
}
Response示例:
{
"jsonrpc": "2.0",
"id": 1, // 对应请求的 ID
"result": {}, // 可选,成功结果
"error": { // 可选,错误信息
"code": 123,
"message": "错误描述",
"data": {} // 可选,附加数据
}
}
3、服务端
服务器提供了为 LLM 大模型添加上下文的基础构件。通过 Propmts(提示词)、Resources(资源)和 Tools(工具)这三种 原语(Primitives), 客户端、服务器与语言模型之间能够实现高效且灵活的交互。
- Prompts
允许服务器定义可复用的提示词模板和工作流,客户端可以轻松将这些模板呈现给用户或 LLM。
如果客户端要使用提示词,需要通过 prompts/get 接口获取提示词详情。 - Resources
服务器通过它可以向客户端提供可读的数据或内容,用作 LLM 交互的上下文信息。每个资源通过 URI 进行标识:[协议]😕/[主机]/[路径],如file:///home/chenmingyong/documents/go.pdf
客户端可以通过 resources/read 接口读取资源内容,只需传入资源的 URI
客户端可以订阅特定资源,资源发生变更时可以通知客户端 - Tools
服务器可通过它向客户端暴露可执行功能,供 LLM 使用(通常需要用户批准,确保人类参与决策)
客户端可通过 tools/call接口发起工具调用请求,由服务器执行具体操作并返回结果。
示例:
s := server.NewMCPServer(
"Server Demo",
"1.0.0",
)
// 定义工具
{
calculatorTool := mcp.NewTool("calculate",
mcp.WithDescription("执行基本的算术运算"),
mcp.WithString("operation",
mcp.Required(),
mcp.Description("要执行的算术运算类型"),
mcp.Enum("add", "subtract", "multiply", "divide"), // 保持英文
),
mcp.WithNumber("x",
mcp.Required(),
mcp.Description("第一个数字"),
),
mcp.WithNumber("y",
mcp.Required(),
mcp.Description("第二个数字"),
),
)
// 服务器添加工具及其处理函数
s.AddTool(calculatorTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
op := request.Params.Arguments["operation"].(string)
x := request.Params.Arguments["x"].(float64)
y := request.Params.Arguments["y"].(float64)
var result float64
switch op {
case "add":
result = x + y
case "subtract":
result = x - y
case "multiply":
result = x * y
case "divide":
if y == 0 {
return nil, errors.New("不允许除以零")
}
result = x / y
}
return mcp.FormatNumberResult(result), nil
})
}
4、客户端
- Roots
Roots 是MCP 协议中的一个概念,用于界定服务器可操作的边界。客户端可以定义 Roots,以告知服务器相关的资源信息及其位置。
root 是客户端建议服务器应关注的 URI。当 客户端 连接到服务器时,它会声明 服务器 应处理哪些 root。虽然这些 root 主要是文件系统路径,也可以是 HTTP URL。
示例:
{
"roots": [
{
"uri": "file:///home/chenmingyong/workspace/frontend",
"name": "Frontend Repository"
},
{
"uri": "https://chenmingyong.cn/",
"name": "API Endpoint"
}
]
} - Sampling
采样是 MCP 协议中一项强大的功能,允许服务器通过客户端向 LLM 大模型请求补全结果,从而实现更复杂的代理行为,同时确保安全性与隐私性。
5、接入外部MCP
在.mcp.json中配置(需要提前申请api_key)
{
"mcpServers": {
"api-server": {
"type": "http",
"url": "{API_BASE_URL:-https://api.example.com/mcp}", "headers": { "Authorization": "Bearer {API_KEY}"
}
}
}
}
四、RAG
RAG(检索增强生成)= 检索技术 + LLM 提示。RAG就是通过检索获取相关的知识并将其融入Prompt,让大模型能够参考相应的知识从而给出合理回答。
1、RAG流程
分为数据准备阶段和应用阶段
数据准备阶段:
- 数据提取
- 文本分割:主要考虑两个因素,1)embedding模型的Tokens限制情况 2)语义完整性对整体的检索效果的影响。
一些常见的文本分割方式:
- 句分割:以"句"的粒度进行切分,保留一个句子的完整语义。常见切分符包括:句号、感叹号、问号、换行符等。
- 固定长度分割:根据embedding模型的token长度限制,将文本分割为固定长度(如1024/512个tokens),这种切分方式会损失很多语义信息,一般通过在头尾增加一定冗余量来缓解。
- 向量化(embedding)
常用的Embedding模型,ChatGPT-Embedding、ERNIE-Embedding V1、M3E、BGE - 数据入库:数据向量化后构建索引,并写入数据库的过程可以概述为数据入库过程
适用于RAG场景的数据库:FAISS、Chromadb、ES、milvus等。这些工具基于近似最近邻居算法,如聚类、树结构或HNSW算法。
应用阶段:
- 用户提问
- 数据检索(召回)
常见的数据检索方法包括:相似性检索、全文检索(倒排索引)等 - 数据重排序
在 LlamaIndex 中,有各种可用的后处理器,根据相似性分数、关键字、元数据过滤掉结果,或使用其他模型(如 LLM)、sentence-transformer 交叉编码器,Cohere 重新排名接口或者基于元数据重排它们。 - 注入Promp
- LLM生成答案
2、RAG技巧
- 查询重写:使用 LLM 来重新表述初始查询,以改进检索。对于复杂的查询,大语言模型能够将其拆分为多个子查询
- 分层索引:创建两个索引,一个由摘要组成,另一个由文档块组成,然后分两步进行搜索,首先通过摘要过滤掉相关文档,然后只在这个相关组内搜索。
- 假设性问题:让 LLM 为每个块生成一个问题,并将这些问题嵌入到向量中,在运行时对这个问题向量的索引执行查询搜索,然后在检索后路由到原始文本块并将它们作为 LLM 获取答案的上下文发送。
- HyDE:反向逻辑方法,LLM 在给定查询的情况下生成一个假设的响应,然后将其向量与查询向量一起使用来提高搜索质量。
- 内容增强:将相关的上下文组合起来供 LLM 推理,以检索较小的块以获得更好的搜索质量。
- 语句窗口检索器:文档中的每个句子单独嵌入,获取最相关的单个句子后,将上下文窗口扩展为检索到的句子前后的 k 个句子,然后将这个扩展的上下文发送到 LLM。
- 自动合并检索器:文档被拆分为较小的子块,这些子块和较大的父块有引用关系。首先在检索过程中获取较小的块,然后如果前 k 个检索到的块中有超过 n 个块链接到同一个父节点(较大的块),将这个父节点替换成给 LLM 的上下文------工作原理类似于自动将一些检索到的块合并到一个更大的父块中。
- 融合检索或混合搜索:结合传统的基于关键字的搜索(稀疏检索算法,如 tf-idf 或搜索行业标准 BM25)和现代语义或向量搜索,并将其结果组合在一个检索结果中。关键是如何组合不同相似度分数的检索结果。这个问题通常通过 Reciprocal Rank Fusion 算法来解决,该算法能有效地对检索结果进行重新排序,以得到最终的输出结果。在 LangChain 中,这种方法是通过 Ensemble Retriever 来实现的,该类将你定义的多个检索器结合起来,比如一个基于 faiss 的向量索引和一个基于 BM25 的检索器,并利用 RRF 算法进行结果的重排。
3、RAG演进
传统RAG的局限性:传统RAG在设计上是将文档分块以便进行检索,然而这种方法忽略了这些块之间的上下文关系。如果意义或上下文跨越多个块,就很难准确回答复杂的问题。
- GraphRAG
GraphRAG是一种结合了知识图谱(KG)和检索增强生成(RAG)的技术,其核心在于利用大语言模型(LLM)从非结构化文本中提取实体和关系,构建结构化的知识图谱,以增强LLM对私有或复杂数据的全局理解和推理能力
流程:
- 在索引/图谱构建阶段,将源文档分块,利用LLM提取实体、关系和声明(Covariates),构建知识图谱;
- 随后应用社区检测算法(如Leiden算法)对知识图谱进行层次化聚类,形成不同粒度的图社区,并为每个社区生成自然语言摘要。
- 在检索阶段,当用户发起查询时,系统通过图检索技术,从构建好的知识图谱中定位与查询意图最相关的子图或社区,并召回相应的社区摘要和实体关系信息作为上下文。在生成阶段,将检索到的图谱上下文(包括社区摘要、实体及关系)与用户查询结合,输入给LLM,生成最终答案
技术优势:
-
上下文的深度关联:图结构提供了更强的语义理解能力,尤其是在需要多跳推理的任务中表现突出 。例如在回答 "A 事件如何间接导致 C 结果" 这类复杂问题时,能通过图谱路径进行多步推理,给出合理答案 。
-
适应复杂知识体系:能够动态整合不同来源的知识 。在科研论文生成场景中,可检索与主题相关的核心文献,利用知识图谱连接文献中的关键实体和观点,生成内容丰富且逻辑流畅的综述 。例如在生成关于人工智能发展趋势的综述时,能融合多篇不同角度的文献知识。
-
LightRAG
LightRAG 是一种优化版的检索增强生成(RAG)框架,旨在通过减少资源消耗和简化系统设计,实现轻量化与高效性 。它强调轻量化和高效性,针对资源受限的场景优化设计 ,适用于移动设备或实时性要求高的系统 。通过在设计中进行一系列优化,在保证生成质量的同时,降低硬件要求和运行成本 ,为移动设备、边缘计算环境等提供优化解决方案 。
- 工作原理
-
图基文本索引:LightRAG 将文本数据构建为图结构进行索引,节点可以是文本中的关键概念、实体等,边表示它们之间的语义关系。例如在一段关于旅游景点介绍的文本中,将景点名称、特色美食、周边交通等分别作为节点,根据文本描述建立如 "景点包含美食""交通连接景点" 等边的关系。
-
双层检索范式:采用低层次和高层次的双层检索机制。低层次检索从基础数据中快速筛选出与查询可能相关的初步信息,高层次检索则基于低层次检索结果,进一步在更精细的层面进行深入检索,以获取更准确和全面的信息。比如用户查询 "北京旅游攻略",低层次检索先从大量旅游文本中快速定位到包含 "北京" 的文档片段,高层次检索再从这些片段中精确查找与旅游攻略相关的详细内容,如景点推荐、游玩路线等。
-
AgenticRAG
Agentic RAG 通过引入能够进行动态决策和工作流优化的自主智能体, 采用迭代细化和自适应检索策略来处理复杂、实时和多领域的查询 。核心在于智能判断何时需要检索,而非对每个查询都盲目执行"检索→生成"流程。
- 工作原理
- 自主决策:代理根据查询复杂度独立评估和管理检索策略 。例如当遇到一个复杂的金融领域问题,如 "分析当前宏观经济形势下,不同行业股票投资组合的风险与收益情况,并给出调整建议",代理会判断需要从多个数据源获取信息,包括经济数据报告、行业研究报告、股票市场数据等,并自主选择合适的检索工具和方法。
- 迭代精炼:包含反馈循环以提高检索准确性和响应相关性 。代理在获取初步检索结果后,会对结果进行评估,如果发现结果不完整或不准确,会再次调整检索策略,重新进行检索。比如第一次检索到的行业研究报告不够新,代理会再次检索更新的报告,并将新结果与之前的进行融合。
- 工作流优化:动态编排任务,使实时应用效率更高 。在处理客户支持问题时,代理可以根据客户问题的紧急程度和类型,合理安排处理顺序,优先解决紧急且重要的问题,同时协调不同的服务资源,如知识库、专家系统等,以快速有效地解决客户问题。
- 核心优势
- 动态适应性:能够根据任务和环境的变化,实时调整检索和生成策略,更好地应对复杂多变的查询 。在金融分析领域,能随时根据市场动态变化调整分析策略和数据检索范围。
- 多步推理能力:通过自主代理的迭代推理,能够处理需要多步思考和分析的复杂问题 。在解决科学研究中的复杂问题时,能逐步推导,给出全面深入的答案。
- 提升用户体验:为用户提供更贴合需求、更准确的回答,在客户支持场景中,大大提高客户满意度 。例如在电商客服中,能快速准确地解决客户关于产品信息、订单问题等各种咨询。
五、Memory
- Claude Code三层记忆结构
Claude Code 的记忆系统是一个自动运转的三层记忆流水线:
- 短期记忆(Session Memory):在后台维护一份结构化的 Markdown 笔记文件,记录当前会话的关键信息。
- 中期记忆(Auto Memory):每轮对话结束后,自动提取你的偏好、踩过的坑等"代码里找不到的经验",并长期保存。
- 长期记忆(Auto Dream):定期在后台清理过期信息、合并重复内容,防止记忆越来越臃肿。
核心原理:后台 fork + prompt cache 共享 + 权限沙箱
- 短期记忆(Session Memory)
每个会话保留一份summary.md会话笔记文件,记录当前会话的关键信息。当token 增长够多 + 工具调用够多时,让 forked agent 用 Edit 工具就地编辑笔记文件
Session Memory 只在当前会话有效,关掉就没了 - 中期记忆(Auto Memory)
每轮对话收尾后,后台 forked agent 从对话中提取值得长期保留的信息。输出md文件和MEMORY.md记忆索引文件,对话时会加载持久记忆索引到上下文,必要时按 query 召回相关 topic files
权限沙箱:forked agent 不是全权操作------它的工具权限被严格限制:Edit / Write 只能写 memory/ 目录,MCP / Agent 等全部拒绝
严格限制MEMORY.md文件的大小:行数限制(200行)、字节限制(25KB) - 长期记忆(Auto Dream)
当积累了足够多的会话后,自动触发一次"梦境"------回顾所有记忆文件和会话转录,合并重复、修正过时信息、修剪冗余。
Dream流程: - Orient(定位): ls 记忆目录 → 读 MEMORY.md → 浏览已有 topic 文件
- Gather(采集新信号):读每日日志 → 找过时的记忆 → grep 转录(窄搜索,只在有明确线索时 grep 特定关键词)
- Consolidate(整合):合并新信号到已有文件 → 把相对日期转绝对日期 → 删除被推翻的旧事实
- Prune and Index(修剪索引):更新 MEMORY.md → 保持 ≤200 行 ≤25KB → 删除过时指针