Agent开发理解

发布时间:2026/6/5 21:31:51

Agent开发理解 何为Agent开发普通的大模型调用很简单发起一次简单的LLM Api调用即可。Agent区分于普通的LLM Api调用其关键在于让无状态的LLM Api调用能好用不仅能够像有状态一样有记忆还能分析思考正确执行。与之延伸而来就有所谓的「记忆历史会话管理」、「工具调用Mcp」Agent开发范式react、planexcute等让LLM Api调用能够拆解问题多次请求共享会话最终实现目标。想要模型能够结合实时知识进而又出现RAG。基本能力开发好了想节省token成本需要利用好LLM 的qv cache增大缓存占比就要在「记忆管理」的基础上加上分层管理区分长短期记忆将系统提示词、工具列表、长期记忆claude.md等不改动的放到提示词前面以便命中前缀缓存还有后续在MCP的基础上提出的「Skill」概念通过渐进式加载的方式减少工具调用token长度。随着对LLM的进一步利用单一的Agent可能无法完成协作任务于是又开始聚焦于 Muti-Agent 开发引申出了A2A协议以便多Agent间的通信并基于此区分各种模式主从、顺序、协作等…Agent开发框架核心抽象Agent开发框架就是方便开发者去实现上述Agent开发过程中涉及的相关场景的。从22年的chatGPT出现到现在的cursor、claude、codex广泛普及AI的发展太迅速了成熟的Agent开发框架也已经出现了不少如langchain、langgraph、spring-AI等作为一个站在巨人肩膀的AI应用开发时常抱着学习态度去了解这些开发框架的实现代码抛开不同框架间的语言差异不谈会发现各个框架的核心抽象都基本一致。Model最基本的一次LLM调用需要明确模型厂商的provider、baseUrl等信息所以需要抽象出Model类各家厂商模型协议不同只在Model类中抽象出call方法上层不关心具体实现。Message / Prompt模型调用需要输入输入可以是提示词也可以是模型上一轮输出提示词又可以进行分层因此对Message/Prompt抽象包含SystemMessage系统提示词UserMessage用户提示词AssistantMessage模型回复ToolMessage工具执行结果PromptTemplate提示词组装schemePrompt 不是一段文本而是一组可组合、可追踪、可插入上下文的结构化消息。Tool模型不只是聊天它要能做事所以出现了ToolMcp/Skill本质上就是一种Tool模型通过function calling/tool calling选择工具框架负责解析参数、执行工具、把结果塞回对话。interfaceTool{name:stringdescription:stringschema:JSONSchemacall(input:unknown):Promiseunknown}Chain / Runnable实际场景往往不是一次模型调用就能解决问题的通常需要多个步骤所以需要把步骤串起来。于是出现了Chain/RunnableRunnable把各种执行组件都统一成input - invoke/stream/batch - output把 AI 应用从“写业务代码调用模型”变成“声明一条数据处理管线”类似于工作流只适用于流程相对固定的场景还算不上Agent。AgentAgent Model Prompt Tools Loop。Agent 的关键是一个循环观察当前状态- 让模型决定下一步- 如果要调用工具执行工具- 把工具结果加入上下文- 再让模型判断- 直到完成经典 ReAct 范式就是Thought - Action - Observation - Thought - Final AnswerclassAgentExecutor{model:ChatModel tools:Tool[]memory:Memoryasyncrun(input){while(!done){constresponseawaitmodel.call(messages)if(response.toolCalls){constresultsawaitrunTools(response.toolCalls)messages.push(results)}else{returnresponse}}}}RAG接着为了引入实时外部知识实现RAG又出现了Document/Retriever/VectorStore具体过程涉及文档加载DocumentLoader、分隔TextSplitter、向量化EmbeddingModel、向量存储VectorStore、向量检索Retriever、重排序Reranker等。其中的Retriever的抽象很重要因为上层 Agent 不应该知道底层是Milvus、PGVector、Elasticsearch、Redis、Chroma还是普通 SQL。interfaceRetriever{retrieve(query:string):PromiseDocument[]}Graph/Node在复杂场景下可以将复杂任务拆解成子任务由多个Agent串行/并行实现因而基于此提出图Graph的概念。Graph每个节点Node是一个Agent当然也可以是Agent之下更小的运行组件如规划节点、检索节点、代码执行节点、审核节点、人类确认节点、总结节点、失败重试节点、分支路由节点等。Checkpoint每个节点的状态记录通过Checkpoint存储Checkpoint保存的是图执行状态快照如当前thread id、当前graph step、当前state values、各channel version、下一步待执行节点、历史状态等让每个具体节点状态都变得可观测。State节点间的共享元数据使用State维护所有节点共享同一份每个节点读取State每返回State的增量更新。一个通用的State定义通常包含typeAgentState{messages:Message[]taskId:stringplan?:string[]currentStep?:numberretrievedDocs?:Document[]toolResults?:ToolResult[]finalAnswer?:string}Memory想要保存跨轮次、跨任务、跨会话的记忆信息又引申出MemoryMemory可以细分出很多类型如长期记忆、短期记忆、规则/流程记忆等。Hooks/Advisor同时节点执行前、执行后可以添加一下Hooks/Advisor拦截操作例如通过这些Hooks来进行人工确认。实际代码编写过程中通常是先建出各个节点然后再建图添加边把一个节点到下一个节点作为一条边例如我参与开源项目spring-ai-aibaba中的一个例子/** * 示例 1: 添加短期内存 */publicstaticvoidaddShortTermMemory(ChatClient.BuilderchatClientBuilder)throwsGraphStateException{// 创建内存检查点器MemorySavercheckpointernewMemorySaver();SaverConfigsaverConfigSaverConfig.builder().register(checkpointer).build();// 定义状态策略KeyStrategyFactorykeyStrategyFactory()-{MapString,KeyStrategykeyStrategyMapnewHashMap();keyStrategyMap.put(messages,newAppendStrategy());returnkeyStrategyMap;};// 创建聊天节点varchatNodenode_async(state-{ListMapString,Stringmessages(ListMapString,String)state.value(messages).orElse(List.of());// 使用 ChatClient 调用 AI 模型ChatClientchatClientchatClientBuilder.build();StringresponsechatClient.prompt().user(messages.get(messages.size()-1).get(content)).call().content();returnMap.of(messages,List.of(Map.of(role,assistant,content,response)));});// 构建图StateGraphstateGraphnewStateGraph(keyStrategyFactory).addNode(chat,chatNode).addEdge(START,chat).addEdge(chat,END);// 编译图CompiledGraphgraphstateGraph.compile(CompileConfig.builder().saverConfig(saverConfig).build());// 第一轮对话RunnableConfigconfigRunnableConfig.builder().threadId(conversation-1).build();graph.invoke(Map.of(messages,List.of(Map.of(role,user,content,你好我是 Bob))),config);// 第二轮对话使用相同的 threadIdgraph.invoke(Map.of(messages,List.of(Map.of(role,user,content,我的名字是什么))),config);// AI 将能够记住之前的对话回答 BobSystem.out.println(Short-term memory example executed);}A2A如果说Tool 是 Agent 调用函数那么A2A是 Agent 调用另一个 Agent。一个具有多Agent节点的Graph可以理解为本地的A2A调用当然也可以通过http、rpc实现远程A2A调用例如配合nacos注册中心进行Agent级别的服务注册、发现。

相关新闻