PageSourceSearch

https://java2ai.com/assets/js/c723b5a2.f4724691.js

js java2ai.com collected 2026-10-03 21:36:17 UTC 42,501 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkspring_ai_alibaba_website=self.webpackChunkspring_ai_alibaba_website||[]).push([[5878],{24938:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>c,frontMatter:()=>t,metadata:()=>s,toc:()=>m});const s=JSON.parse('{"id":"frameworks/agent-framework/tutorials/memory","title":"Memory \u77ed\u671f\u8bb0\u5fc6","description":"\u4e86\u89e3\u5982\u4f55\u4f7f\u7528\u77ed\u671f\u8bb0\u5fc6\u8ba9Agent\u8bb0\u4f4f\u5148\u524d\u4ea4\u4e92\uff0c\u7ba1\u7406\u5bf9\u8bdd\u5386\u53f2\u548c\u7ebf\u7a0b\u7ea7\u6301\u4e45\u5316","source":"@site/docs/frameworks/agent-framework/tutorials/memory.md","sourceDirName":"frameworks/agent-framework/tutorials","slug":"/frameworks/agent-framework/tutorials/memory","permalink":"/docs/frameworks/agent-framework/tutorials/memory","draft":false,"unlisted":false,"editUrl":"https://github.com/spring-ai-alibaba/website/tree/main/docs/frameworks/agent-framework/tutorials/memory.md","tags":[],"version":"current","lastUpdatedBy":"Ken Liu","lastUpdatedAt":1766364541000,"frontMatter":{"title":"Memory \u77ed\u671f\u8bb0\u5fc6","description":"\u4e86\u89e3\u5982\u4f55\u4f7f\u7528\u77ed\u671f\u8bb0\u5fc6\u8ba9Agent\u8bb0\u4f4f\u5148\u524d\u4ea4\u4e92\uff0c\u7ba1\u7406\u5bf9\u8bdd\u5386\u53f2\u548c\u7ebf\u7a0b\u7ea7\u6301\u4e45\u5316","keywords":["\u77ed\u671f\u8bb0\u5fc6","Short-term Memory","\u5bf9\u8bdd\u5386\u53f2","\u7ebf\u7a0b","Thread","Checkpointer","\u4f1a\u8bdd\u7ba1\u7406","\u4e0a\u4e0b\u6587\u7a97\u53e3"]},"sidebar":"docsSidebar","previous":{"title":"Tools \u5de5\u5177","permalink":"/docs/frameworks/agent-framework/tutorials/tools"},"next":{"title":"Hooks \u548c Interceptors","permalink":"/docs/frameworks/agent-framework/tutorials/hooks"}}');var o=a(74848),i=a(28453);const t={title:"Memory \u77ed\u671f\u8bb0\u5fc6",description:"\u4e86\u89e3\u5982\u4f55\u4f7f\u7528\u77ed\u671f\u8bb0\u5fc6\u8ba9Agent\u8bb0\u4f4f\u5148\u524d\u4ea4\u4e92\uff0c\u7ba1\u7406\u5bf9\u8bdd\u5386\u53f2\u548c\u7ebf\u7a0b\u7ea7\u6301\u4e45\u5316",keywords:["\u77ed\u671f\u8bb0\u5fc6","Short-term Memory","\u5bf9\u8bdd\u5386\u53f2","\u7ebf\u7a0b","Thread","Checkpointer","\u4f1a\u8bdd\u7ba1\u7406","\u4e0a\u4e0b\u6587\u7a97\u53e3"]},r=void 0,l={},m=[{value:"\u6982\u8ff0",id:"\u6982\u8ff0",level:2},{value:"\u7406\u89e3 ReactAgent \u4e2d\u7684\u77ed\u671f\u8bb0\u5fc6",id:"\u7406\u89e3-reactagent-\u4e2d\u7684\u77ed\u671f\u8bb0\u5fc6",level:2},{value:"\u8bb0\u5fc6\u5e26\u6765\u7684\u4e0a\u4e0b\u6587\u8fc7\u957f\u95ee\u9898",id:"\u8bb0\u5fc6\u5e26\u6765\u7684\u4e0a\u4e0b\u6587\u8fc7\u957f\u95ee\u9898",level:2},{value:"\u4f7f\u7528\u65b9\u6cd5",id:"\u4f7f\u7528\u65b9\u6cd5",level:2},{value:"\u5728\u751f\u4ea7\u73af\u5883\u4e2d",id:"\u5728\u751f\u4ea7\u73af\u5883\u4e2d",level:3},{value:"\u81ea\u5b9a\u4e49 Agent \u8bb0\u5fc6",id:"\u81ea\u5b9a\u4e49-agent-\u8bb0\u5fc6",level:2},{value:"\u5e38\u89c1\u6a21\u5f0f",id:"\u5e38\u89c1\u6a21\u5f0f",level:2},{value:"\u4fee\u526a\u6d88\u606f",id:"\u4fee\u526a\u6d88\u606f",level:3},{value:"\u5220\u9664\u6d88\u606f",id:"\u5220\u9664\u6d88\u606f",level:3},{value:"\u603b\u7ed3\u6d88\u606f",id:"\u603b\u7ed3\u6d88\u606f",level:3},{value:"\u8bbf\u95ee\u8bb0\u5fc6",id:"\u8bbf\u95ee\u8bb0\u5fc6",level:2},{value:"\u5de5\u5177",id:"\u5de5\u5177",level:3},{value:"\u5728\u5de5\u5177\u4e2d\u8bfb\u53d6\u77ed\u671f\u8bb0\u5fc6",id:"\u5728\u5de5\u5177\u4e2d\u8bfb\u53d6\u77ed\u671f\u8bb0\u5fc6",level:4},{value:"\u4ece\u5de5\u5177\u5199\u5165\u77ed\u671f\u8bb0\u5fc6",id:"\u4ece\u5de5\u5177\u5199\u5165\u77ed\u671f\u8bb0\u5fc6",level:4},{value:"\u63d0\u793a",id:"\u63d0\u793a",level:3},{value:"Before Model",id:"before-model",level:3},{value:"After Model",id:"after-model",level:3},{value:"\u76f8\u5173\u8d44\u6e90",id:"\u76f8\u5173\u8d44\u6e90",level:2}];function g(e){const n={a:"a",blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components},{Code:a}=n;return a||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Code",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h2,{id:"\u6982\u8ff0",children:"\u6982\u8ff0"}),"\n",(0,o.jsx)(n.p,{children:"\u8bb0\u5fc6\u53ef\u4ee5\u8ba9 Agent \u8bb0\u4f4f\u4e4b\u524d\u7684\u4f1a\u8bdd\u5185\u5bb9\u3002\u5bf9\u4e8e AI Agent\uff0c\u8bb0\u5fc6\u81f3\u5173\u91cd\u8981\uff0c\u56e0\u4e3a\u5b83\u8ba9\u5b83\u4eec\u80fd\u591f\u8bb0\u4f4f\u5148\u524d\u7684\u4ea4\u4e92\u3001\u4ece\u53cd\u9988\u4e2d\u5b66\u4e60\u5e76\u9002\u5e94\u7528\u6237\u504f\u597d\u3002\u968f\u7740 Agent \u5904\u7406\u66f4\u590d\u6742\u7684\u4efb\u52a1\u548c\u5927\u91cf\u7528\u6237\u4ea4\u4e92\uff0c\u8fd9\u79cd\u80fd\u529b\u5bf9\u4e8e\u6548\u7387\u548c\u7528\u6237\u6ee1\u610f\u5ea6\u90fd\u53d8\u5f97\u81f3\u5173\u91cd\u8981\u3002"}),"\n",(0,o.jsx)(n.p,{children:"\u77ed\u671f\u8bb0\u5fc6\u8ba9\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u80fd\u591f\u5728\u5355\u4e2a\u7ebf\u7a0b\u6216\u4f1a\u8bdd\u4e2d\u8bb0\u4f4f\u5148\u524d\u7684\u4ea4\u4e92\u3002"}),"\n",(0,o.jsxs)(n.blockquote,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"\u6ce8\u610f"}),"\uff1a\u4f1a\u8bdd\u53ef\u4ee5\u9694\u79bb\u540c\u4e00\u4e2a Agent \u5b9e\u4f8b\u4e2d\u7684\u591a\u4e2a\u4e0d\u540c\u4ea4\u4e92\uff0c\u7c7b\u4f3c\u4e8e\u7535\u5b50\u90ae\u4ef6\u5728\u5355\u4e2a\u5bf9\u8bdd\u4e2d\u5206\u7ec4\u6d88\u606f\u7684\u65b9\u5f0f\u3002"]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"\u7406\u89e3-reactagent-\u4e2d\u7684\u77ed\u671f\u8bb0\u5fc6",children:"\u7406\u89e3 ReactAgent \u4e2d\u7684\u77ed\u671f\u8bb0\u5fc6"}
1),"\n",(0,o.jsx)(n.p,{children:"Spring AI Alibaba \u5c06\u77ed\u671f\u8bb0\u5fc6\u4f5c\u4e3a Agent \u72b6\u6001\u7684\u4e00\u90e8\u5206\u8fdb\u884c\u7ba1\u7406\u3002"}),"\n",(0,o.jsx)(n.p,{children:"\u901a\u8fc7\u5c06\u8fd9\u4e9b\u5b58\u50a8\u5728 Graph \u7684\u72b6\u6001\u4e2d\uff0cAgent \u53ef\u4ee5\u8bbf\u95ee\u7ed9\u5b9a\u5bf9\u8bdd\u7684\u5b8c\u6574\u4e0a\u4e0b\u6587\uff0c\u540c\u65f6\u4fdd\u6301\u4e0d\u540c\u5bf9\u8bdd\u4e4b\u95f4\u7684\u5206\u79bb\u3002\u72b6\u6001\u4f7f\u7528 checkpointer \u6301\u4e45\u5316\u5230\u6570\u636e\u5e93\uff08\u6216\u5185\u5b58\uff09\uff0c\u4ee5\u4fbf\u53ef\u4ee5\u968f\u65f6\u6062\u590d\u7ebf\u7a0b\u3002\u77ed\u671f\u8bb0\u5fc6\u5728\u8c03\u7528 Agent \u6216\u5b8c\u6210\u6b65\u9aa4\uff08\u5982\u5de5\u5177\u8c03\u7528\uff09\u65f6\u66f4\u65b0\uff0c\u5e76\u5728\u6bcf\u4e2a\u6b65\u9aa4\u5f00\u59cb\u65f6\u8bfb\u53d6\u72b6\u6001\u3002"}),"\n",(0,o.jsx)(n.h2,{id:"\u8bb0\u5fc6\u5e26\u6765\u7684\u4e0a\u4e0b\u6587\u8fc7\u957f\u95ee\u9898",children:"\u8bb0\u5fc6\u5e26\u6765\u7684\u4e0a\u4e0b\u6587\u8fc7\u957f\u95ee\u9898"}),"\n",(0,o.jsx)(n.p,{children:"\u4fdd\u7559\u6240\u6709\u5bf9\u8bdd\u5386\u53f2\u662f\u5b9e\u73b0\u77ed\u671f\u8bb0\u5fc6\u6700\u5e38\u89c1\u7684\u5f62\u5f0f\u3002\u4f46\u8f83\u957f\u7684\u5bf9\u8bdd\u5bf9\u5386\u53f2\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5927\u6a21\u578b LLM \u4e0a\u4e0b\u6587\u7a97\u53e3\u8d85\u9650\uff0c\u5bfc\u81f4\u4e0a\u4e0b\u6587\u4e22\u5931\u6216\u62a5\u9519\u3002"}),"\n",(0,o.jsx)(n.p,{children:'\u5373\u4f7f\u4f60\u5728\u4f7f\u7528\u7684\u5927\u6a21\u578b\u4e0a\u4e0b\u6587\u957f\u5ea6\u8db3\u591f\u5927\uff0c\u5927\u591a\u6570\u6a21\u578b\u5728\u5904\u7406\u8f83\u957f\u4e0a\u4e0b\u6587\u65f6\u7684\u8868\u73b0\u4ecd\u7136\u5f88\u5dee\u3002\u56e0\u4e3a\u5f88\u591a\u6a21\u578b\u4f1a\u88ab\u8fc7\u65f6\u6216\u504f\u79bb\u4e3b\u9898\u7684\u5185\u5bb9"\u5206\u6563\u6ce8\u610f\u529b"\u3002\u540c\u65f6\uff0c\u8fc7\u957f\u7684\u4e0a\u4e0b\u6587\uff0c\u8fd8\u4f1a\u5e26\u6765\u54cd\u5e94\u65f6\u95f4\u53d8\u957f\u3001Token \u6210\u672c\u589e\u52a0\u7b49\u95ee\u9898\u3002'}),"\n",(0,o.jsxs)(n.p,{children:["\u5728 Spring AI ALibaba \u4e2d\uff0cReactAgent \u4f7f\u7528 ",(0,o.jsx)(n.a,{href:"/docs/frameworks/agent-framework/tutorials/messages",children:"messages"}),' \u8bb0\u5f55\u548c\u4f20\u9012\u4e0a\u4e0b\u6587\uff0c\u5176\u4e2d\u5305\u62ec\u6307\u4ee4\uff08SystemMessage\uff09\u548c\u8f93\u5165\uff08UserMessage\uff09\u3002\u5728 ReactAgent \u4e2d\uff0c\u6d88\u606f\uff08Message\uff09\u5728\u7528\u6237\u8f93\u5165\u548c\u6a21\u578b\u54cd\u5e94\u4e4b\u95f4\u4ea4\u66ff\uff0c\u5bfc\u81f4\u6d88\u606f\u5217\u8868\u968f\u7740\u65f6\u95f4\u7684\u63a8\u79fb\u53d8\u5f97\u8d8a\u6765\u8d8a\u957f\u3002\u7531\u4e8e\u4e0a\u4e0b\u6587\u7a97\u53e3\u6709\u9650\uff0c\u8bb8\u591a\u5e94\u7528\u7a0b\u5e8f\u53ef\u4ee5\u4ece\u4f7f\u7528\u6280\u672f\u6765\u79fb\u9664\u6216"\u5fd8\u8bb0"\u8fc7\u65f6\u4fe1\u606f\u4e2d\u53d7\u76ca\uff0c\u5373 \u201c\u4e0a\u4e0b\u6587\u5de5\u7a0b\u201d\u3002']}),"\n",(0,o.jsx)(n.h2,{id:"\u4f7f\u7528\u65b9\u6cd5",children:"\u4f7f\u7528\u65b9\u6cd5"}),"\n",(0,o.jsxs)(n.p,{children:["\u5728 Spring AI Alibaba \u4e2d\uff0c\u8981\u5411 Agent \u6dfb\u52a0\u77ed\u671f\u8bb0\u5fc6\uff08\u4f1a\u8bdd\u7ea7\u6301\u4e45\u5316\uff09\uff0c\u4f60\u9700\u8981\u5728\u521b\u5efa Agent \u65f6\u6307\u5b9a ",(0,o.jsx)(n.code,{children:"checkpointer"}),"\u3002"]}),"\n",(0,o.jsx)(a,{language:"java",title:"\u914d\u7f6e\u77ed\u671f\u8bb0\u5fc6\u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import com.alibaba.cloud.ai.graph.agent.ReactAgent;\n\nimport com.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;\nimport com.alibaba.cloud.ai.graph.RunnableConfig;\n\n// \u914d\u7f6e checkpointer\nReactAgent agent = ReactAgent.builder()\n  .name("my_agent")\n  .model(chatModel)\n  .tools(getUserInfoTool)\n  .saver(new MemorySaver())\n  .build();\n\n// \u4f7f\u7528 thread_id \u7ef4\u62a4\u5bf9\u8bdd\u4e0a\u4e0b\u6587\nRunnableConfig config = RunnableConfig.builder()\n  .threadId("1") // threadId \u6307\u5b9a\u4f1a\u8bdd ID\n  .build();\n\nagent.call("\u4f60\u597d\uff01\u6211\u53eb Bob\u3002", config);'}),"\n",(0,o.jsx)(n.h3,{id:"\u5728\u751f\u4ea7\u73af\u5883\u4e2d",children:"\u5728\u751f\u4ea7\u73af\u5883\u4e2d"}),"\n",(0,o.jsx)(n.p,{children:"\u5728\u751f\u4ea7\u73af\u5883\u4e2d\uff0c\u4f7f\u7528\u6570\u636e\u5e93\u652f\u6301\u7684 checkpointer\uff1a"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"\u793a\u4f8b\uff1a\u4f7f\u7528 Redis Checkpointer"}),"\uff1a"]}),"\n",(0,o.jsx)(a,{language:"java",title:"\u4f7f\u7528 Redis Checkpointer \u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import 
1com.alibaba.cloud.ai.graph.checkpoint.savers.RedisSaver;\nimport org.redisson.api.RedissonClient;\n\n// \u914d\u7f6e Redis checkpointer\nRedisSaver redisSaver = new RedisSaver(redissonClient);\n\nReactAgent agent = ReactAgent.builder()\n  .name("my_agent")\n  .model(chatModel)\n  .tools(getUserInfoTool)\n  .saver(redisSaver)\n  .build();'}),"\n",(0,o.jsx)(n.h2,{id:"\u81ea\u5b9a\u4e49-agent-\u8bb0\u5fc6",children:"\u81ea\u5b9a\u4e49 Agent \u8bb0\u5fc6"}),"\n",(0,o.jsxs)(n.p,{children:["\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cAgent \u4f7f\u7528\u72b6\u6001\u901a\u8fc7 ",(0,o.jsx)(n.code,{children:"messages"})," \u952e\u7ba1\u7406\u77ed\u671f\u8bb0\u5fc6\uff0c\u7279\u522b\u662f\u5bf9\u8bdd\u5386\u53f2\u3002"]}),"\n",(0,o.jsx)(n.p,{children:"\u4f60\u53ef\u4ee5\u901a\u8fc7\u5728\u5de5\u5177\u6216 Hook \u4e2d\u8bbf\u95ee\u548c\u4fee\u6539\u72b6\u6001\u6765\u6269\u5c55\u8bb0\u5fc6\u529f\u80fd\u3002"}),"\n",(0,o.jsx)(a,{language:"java",title:"\u81ea\u5b9a\u4e49\u8bb0\u5fc6 Hook \u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import com.alibaba.cloud.ai.graph.agent.hook.ModelHook;\nimport com.alibaba.cloud.ai.graph.agent.hook.HookPosition;\nimport com.alibaba.cloud.ai.graph.OverAllState;\nimport com.alibaba.cloud.ai.graph.RunnableConfig;\nimport org.springframework.ai.chat.messages.Message;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.concurrent.CompletableFuture;\n\n// \u5728 Hook \u4e2d\u8bbf\u95ee\u548c\u4fee\u6539\u72b6\u6001\npublic class CustomMemoryHook extends ModelHook {\n\n  @Override\n  public String getName() {\n      return "custom_memory";\n  }\n\n  @Override\n  public HookPosition[] getHookPositions() {\n      return new HookPosition[]{HookPosition.BEFORE_MODEL};\n  }\n\n  @Override\n  public CompletableFuture<Map<String, Object>> beforeModel(OverAllState state, RunnableConfig config) {\n      // \u8bbf\u95ee\u6d88\u606f\u5386\u53f2\n      Optional<Object> messagesOpt = state.value("messages");\n      if (messagesOpt.isPresent()) {\n          List<Message> messages = (List<Message>) messagesOpt.get();\n          // \u5904\u7406\u6d88\u606f...\n      }\n\n      // \u6dfb\u52a0\u81ea\u5b9a\u4e49\u72b6\u6001\n      return CompletableFuture.completedFuture(Map.of(\n          "user_id", "user_123",\n          "preferences", Map.of("theme", "dark")\n      ));\n  }\n\n  @Override\n  public CompletableFuture<Map<String, Object>> afterModel(OverAllState state, RunnableConfig config) {\n      return CompletableFuture.completedFuture(Map.of());\n  }\n}'}),"\n",(0,o.jsx)(n.h2,{id:"\u5e38\u89c1\u6a21\u5f0f",children:"\u5e38\u89c1\u6a21\u5f0f"}),"\n",(0,o.jsxs)(n.p,{children:["\u542f\u7528",(0,o.jsx)(n.a,{href:"#%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95",children:"\u77ed\u671f\u8bb0\u5fc6"}),"\u540e\uff0c\u957f\u5bf9\u8bdd\u53ef\u80fd\u8d85\u8fc7 LLM \u7684\u4e0a\u4e0b\u6587\u7a97\u53e3\u3002\u5e38\u89c1\u7684\u89e3\u51b3\u65b9\u6848\u5305\u62ec\uff1a"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"\u4fee\u526a\u6d88\u606f\u3002\u5728\u8c03\u7528 LLM \u4e4b\u524d\u79fb\u9664\u524d N \u6761\u6216\u540e N \u6761\u6d88\u606f"}),"\n",(0,o.jsx)(n.li,{children:"\u5220\u9664\u6d88\u606f\u3002\u4ece Graph \u72b6\u6001\u4e2d\u6c38\u4e45\u5220\u9664\u6d88\u606f"}),"\n",(0,o.jsx)(n.li,{children:"\u603b\u7ed3\u6d88\u606f\u3002\u603b\u7ed3\u5386\u53f2\u4e2d\u8f83\u65e9\u7684\u6d88\u606f\u5e76\u7528\u6458\u8981\u66ff\u6362\u5b83\u4eec"}),"\n",(0,o.jsx)(n.li,{children:"\u81ea\u5b9a\u4e49\u7b56\u7565\u3002\u81ea\u5b9a\u4e49\u7b56\u7565\uff08\u4f8b\u5982\u6d88\u606f\u8fc7\u6ee4\u7b49\uff09"}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"\u8fd9\u5141\u8bb8 Agent \u5728 reasoning-acting \u5faa\u73af\u4e2d\u6301\u7eed\u8ddf\u8e2a\u5bf9\u8bdd\u800c\u4e0d\u8d85\u8fc7 LLM \u7684\u4e0a\u4e0b\u6587\u7a97\u53e3\u3002"}),"\n",(0,o.jsx)(n.h3,{id:"\u4fee\u526a\u6d88\u606f",children:"\u4fee\u526a\u6d88\u606f"}),"\n",(0,o.jsx)(n.p,{children:"\u5927\u591a\u6570 LLM \u90fd\u6709\u6700\u5927\u652f\u6301\u7684\u4e0a\u4e0b\u6587\u7a97\u53e3\uff08\u4ee5 token \u8ba1\uff09\u3002"}),"\n",(0,o.jsx)(n.p,{children:"\u51b3\u5b9a\u4f55\u65f6\u622a\u65ad\u6d88\u606f\u7684\u4e00\u79cd\u65b9\u6cd5\u662f\u8ba1\u7b97\u6d88\u606f\u5386\u53f2\u4e2d\u7684 token \u6570\u91cf\uff0c\u5e76\u5728\u63a5\u8fd1\u8be5\u9650\u5236\u65f6\u8fdb\u884c\u622a\u65ad\u3002"}),"\n",(0,o.jsxs)(n.p,{children:["\u8981\u5728 Agent \u4e2d\u4fee\u526a\u6d88\u606f\u5386\u53f2\uff0c\u8bf7\u4f7f\u7528 ",(0,o.jsx)(n.code,{children:"MessagesModelHook"}),"\uff1a"]}),"\n",(0,o.jsx)(a,{language:"java",title:"MessageTrimmingHook \u4fee\u526a\u6d88\u606f\u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import 
1com.alibaba.cloud.ai.graph.agent.hook.HookPosition;\nimport com.alibaba.cloud.ai.graph.agent.hook.HookPositions;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.MessagesModelHook;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.AgentCommand;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.UpdatePolicy;\nimport com.alibaba.cloud.ai.graph.RunnableConfig;\nimport org.springframework.ai.chat.messages.Message;\nimport java.util.ArrayList;\nimport java.util.List;\n\n@HookPositions({HookPosition.BEFORE_MODEL})\npublic class MessageTrimmingHook extends MessagesModelHook {\n\n  private static final int MAX_MESSAGES = 3;\n\n  @Override\n  public String getName() {\n      return "message_trimming";\n  }\n\n  @Override\n  public AgentCommand beforeModel(List<Message> previousMessages, RunnableConfig config) {\n      if (previousMessages.size() <= MAX_MESSAGES) {\n          return new AgentCommand(previousMessages); // \u65e0\u9700\u66f4\u6539\n      }\n\n      // \u4fdd\u7559\u7b2c\u4e00\u6761\u6d88\u606f\u548c\u6700\u540e\u51e0\u6761\u6d88\u606f\n      Message firstMsg = previousMessages.get(0);\n      int keepCount = previousMessages.size() % 2 == 0 ? 3 : 4;\n      List<Message> recentMessages = previousMessages.subList(\n          previousMessages.size() - keepCount,\n          previousMessages.size()\n      );\n\n      List<Message> trimmedMessages = new ArrayList<>();\n      trimmedMessages.add(firstMsg);\n      trimmedMessages.addAll(recentMessages);\n\n      // \u4f7f\u7528 REPLACE \u7b56\u7565\u66ff\u6362\u6d88\u606f\u5217\u8868\uff0c\u53ea\u4fdd\u7559\u9700\u8981\u7684\u6d88\u606f\n      return new AgentCommand(trimmedMessages, UpdatePolicy.REPLACE);\n  }\n}\n\n// \u4f7f\u7528\nReactAgent agent = ReactAgent.builder()\n  .name("my_agent")\n  .model(chatModel)\n  .tools(tools)\n  .hooks(new MessageTrimmingHook())\n  .saver(new MemorySaver())\n  .build();\n\nRunnableConfig config = RunnableConfig.builder()\n  .threadId("1")\n  .build();\n\nagent.call("\u4f60\u597d\uff0c\u6211\u53eb bob", config);\nagent.call("\u5199\u4e00\u9996\u5173\u4e8e\u732b\u7684\u77ed\u8bd7", config);\nagent.call("\u73b0\u5728\u5bf9\u72d7\u505a\u540c\u6837\u7684\u4e8b\u60c5", config);\nAssistantMessage finalResponse = agent.call("\u6211\u53eb\u4ec0\u4e48\u540d\u5b57\uff1f", config);\n\nSystem.out.println(finalResponse.getText());\n// \u8f93\u51fa\uff1a\u4f60\u7684\u540d\u5b57\u662f Bob\u3002\u4f60\u4e4b\u524d\u544a\u8bc9\u6211\u7684\u3002'}),"\n",(0,o.jsx)(n.h3,{id:"\u5220\u9664\u6d88\u606f",children:"\u5220\u9664\u6d88\u606f"}),"\n",(0,o.jsx)(n.p,{children:"\u4f60\u53ef\u4ee5\u4ece Graph \u72b6\u6001\u4e2d\u5220\u9664\u6d88\u606f\u4ee5\u7ba1\u7406\u6d88\u606f\u5386\u53f2\u3002"}),"\n",(0,o.jsx)(n.p,{children:"\u8fd9\u5728\u4f60\u60f3\u8981\u5220\u9664\u7279\u5b9a\u6d88\u606f\u6216\u6e05\u9664\u6574\u4e2a\u6d88\u606f\u5386\u53f2\u65f6\u5f88\u6709\u7528\u3002"}),"\n",(0,o.jsx)(n.p,{children:"\u8981\u4ece Graph \u72b6\u6001\u4e2d\u5220\u9664\u6d88\u606f\uff0c\u4f60\u53ef\u4ee5\u5728 Hook \u4e2d\u8fd4\u56de\u65b0\u7684\u6d88\u606f\u5217\u8868\uff1a"}),"\n",(0,o.jsx)(a,{language:"java",title:"MessageDeletionHook \u5220\u9664\u6d88\u606f\u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import com.alibaba.cloud.ai.graph.agent.hook.HookPosition;\nimport com.alibaba.cloud.ai.graph.agent.hook.HookPositions;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.MessagesModelHook;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.AgentCommand;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.UpdatePolicy;\nimport com.alibaba.cloud.ai.graph.RunnableConfig;\nimport org.springframework.ai.chat.messages.Message;\nimport java.util.List;\n\n@HookPositions({HookPosition.AFTER_MODEL})\npublic class MessageDeletionHook extends MessagesModelHook {\n\n  @Override\n  public String getName() {\n      return "message_deletion";\n  }\n\n  @Override\n  public AgentCommand afterModel(List<Message>
1 previousMessages, RunnableConfig config) {\n      if (previousMessages.size() > 2) {\n          // \u5220\u9664\u6700\u65e9\u7684\u4e24\u6761\u6d88\u606f\uff0c\u53ea\u4fdd\u7559\u5269\u4f59\u7684\u6d88\u606f\n          List<Message> remainingMessages = previousMessages.subList(2, previousMessages.size());\n          return new AgentCommand(remainingMessages, UpdatePolicy.REPLACE);\n      }\n\n      return new AgentCommand(previousMessages);\n  }\n}'}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"\u5220\u9664\u6240\u6709\u6d88\u606f"}),"\uff1a"]}),"\n",(0,o.jsx)(a,{language:"java",title:"ClearAllMessagesHook \u5220\u9664\u6240\u6709\u6d88\u606f\u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import com.alibaba.cloud.ai.graph.agent.hook.HookPosition;\nimport com.alibaba.cloud.ai.graph.agent.hook.HookPositions;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.MessagesModelHook;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.AgentCommand;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.UpdatePolicy;\nimport com.alibaba.cloud.ai.graph.RunnableConfig;\nimport org.springframework.ai.chat.messages.Message;\nimport java.util.ArrayList;\nimport java.util.List;\n\n@HookPositions({HookPosition.AFTER_MODEL})\npublic class ClearAllMessagesHook extends MessagesModelHook {\n\n  @Override\n  public String getName() {\n      return "clear_all_messages";\n  }\n\n  @Override\n  public AgentCommand afterModel(List<Message> previousMessages, RunnableConfig config) {\n      // \u5220\u9664\u6240\u6709\u6d88\u606f\uff0c\u8fd4\u56de\u7a7a\u5217\u8868\n      return new AgentCommand(new ArrayList<>(), UpdatePolicy.REPLACE);\n  }\n}'}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"\u8b66\u544a"}),"\uff1a\u5220\u9664\u6d88\u606f\u65f6\uff0c",(0,o.jsx)(n.strong,{children:"\u786e\u4fdd"}),"\u751f\u6210\u7684\u6d88\u606f\u5386\u53f2\u6709\u6548\u3002\u68c0\u67e5\u4f60\u4f7f\u7528\u7684 LLM \u63d0\u4f9b\u5546\u7684\u9650\u5236\u3002\u4f8b\u5982\uff1a"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\u67d0\u4e9b\u63d0\u4f9b\u5546\u671f\u671b\u6d88\u606f\u5386\u53f2\u4ee5 ",(0,o.jsx)(n.code,{children:"user"})," \u6d88\u606f\u5f00\u59cb"]}),"\n",(0,o.jsxs)(n.li,{children:["\u5927\u591a\u6570\u63d0\u4f9b\u5546\u8981\u6c42\u5e26\u6709\u5de5\u5177\u8c03\u7528\u7684 ",(0,o.jsx)(n.code,{children:"assistant"})," \u6d88\u606f\u540e\u8ddf\u76f8\u5e94\u7684 ",(0,o.jsx)(n.code,{children:"tool"})," \u7ed3\u679c\u6d88\u606f"]}),"\n"]}),"\n",(0,o.jsx)(a,{language:"java",title:"DeleteOldMessagesHook \u5220\u9664\u65e7\u6d88\u606f\u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import com.alibaba.cloud.ai.graph.agent.hook.HookPosition;\nimport com.alibaba.cloud.ai.graph.agent.hook.HookPositions;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.MessagesModelHook;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.AgentCommand;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.UpdatePolicy;\nimport com.alibaba.cloud.ai.graph.RunnableConfig;\nimport org.springframework.ai.chat.messages.Message;\nimport java.util.List;\n\n@HookPositions({HookPosition.AFTER_MODEL})\npublic class DeleteOldMessagesHook extends MessagesModelHook {\n\n  @Override\n  public String getName() {\n      return "delete_old_messages";\n  }\n\n  @Override\n  public AgentCommand afterModel(List<Message> previousMessages, RunnableConfig config) {\n      if (previousMessages.size() > 2) {\n          // \u5220\u9664\u6700\u65e9\u7684\u4e24\u6761\u6d88\u606f\uff0c\u53ea\u4fdd\u7559\u5269\u4f59\u7684\u6d88\u606f\n          List<Message> remainingMessages = previousMessages.subList(2, previousMessages.size());\n          return new AgentCommand(remainingMessages, UpdatePolicy.REPLACE);\n      }\n\n      return new AgentCommand(previousMessages);\n  }\n}\n\nReactAgent agent = ReactAgent.builder()\n  .name("my_agent")\n  .model(chatModel)\n  .systemPrompt("\u8bf7\u7b80\u6d01\u660e\u4e86\u3002")\n  .hooks(new DeleteOldMessagesHook())\n  .saver(new MemorySaver())\n  .build();\n\nRunnableConfig config = RunnableConfig.builder()\n  .threadId("1")\n  .build();\n\n// \u7b2c\u4e00\u6b21\u8c03\u7528\nagent.call("\u4f60\u597d\uff01\u6211\u662f bob", config);\n// \u8f93\u51fa\uff1a[(\'human\', "\u4f60\u597d\uff01\u6211\u662f bob"), (\'assistant\', \'\u4f60\u597d Bob\uff01\u5f88\u9ad8\u5174\u89c1\u5230\u4f60...\')]\n\n// \u7b2c\u4e8c\u6b21\u8c03\u7528\nagent.call("\u6211\u53eb\u4ec0\u4e48\u540d\u5b57\uff1f", config);\n// \u8f93\u51fa\uff1a[(\'human\', "\u6211\u53eb\u4ec0\u4e48\u540d\u5b57\uff1f"), (\'assistant\', \'\u4f60\u7684\u540d\u5b57\u662f Bob...\')]'}),"\n",(0,o.jsx)(n.h3,{id:"\u603b\u7ed3\u6d88\u606f",children:"\u603b\u7ed3\u6d88\u606f"}),"\n",(0,o.jsx)(n.p,{children:"\u5982\u4e0a\u6240\u793a\uff0c\u4fee\u526a\u6216\u5220\u9664\u6d88\u606f\u7684\u95ee\u9898\u5728\u4e8e\u4f60\u53ef\u80fd\u4f1a\u4e22\u5931\u6d88\u606f\u961f\u5217\u6dd8\u6c70\u7684\u4fe1\u606f\u3002\u56e0\u6b64\uff0c\u4e00\u4e9b\u5e94\u7528\u7a0b\u5e8f\u53d7\u76ca\u4e8e\u4f7f\u7528\u804a\u5929\u6a21\u578b\u603b\u7ed3\u6d88\u606f\u5386\u53f2\u7684\u66f4\u590d\u6742\u65b9\u6cd5\u3002"}),"\n",(0,o.jsx)(n.p,{children:"\u8981\u5728 Agent \u4e2d\u603b\u7ed3\u6d88\u606f\u5386\u53f2\uff0c\u53ef\u4ee5\u4f7f\u7528\u81ea\u5b9a\u4e49 Hook\uff1a"}),"\n",(0,o.jsx)(a,{language:"java",title:"MessageSummarizationHook \u
1603b\u7ed3\u6d88\u606f\u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import com.alibaba.cloud.ai.graph.agent.hook.HookPosition;\nimport com.alibaba.cloud.ai.graph.agent.hook.HookPositions;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.MessagesModelHook;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.AgentCommand;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.UpdatePolicy;\nimport com.alibaba.cloud.ai.graph.RunnableConfig;\nimport org.springframework.ai.chat.model.ChatModel;\nimport org.springframework.ai.chat.model.ChatResponse;\nimport org.springframework.ai.chat.messages.Message;\nimport org.springframework.ai.chat.messages.SystemMessage;\nimport org.springframework.ai.chat.messages.UserMessage;\nimport org.springframework.ai.chat.prompt.Prompt;\nimport java.util.ArrayList;\nimport java.util.List;\n\n@HookPositions({HookPosition.BEFORE_MODEL})\npublic class MessageSummarizationHook extends MessagesModelHook {\n\n  private final ChatModel summaryModel;\n  private final int maxTokensBeforeSummary;\n  private final int messagesToKeep;\n\n  public MessageSummarizationHook(\n      ChatModel summaryModel,\n      int maxTokensBeforeSummary,\n      int messagesToKeep\n  ) {\n      this.summaryModel = summaryModel;\n      this.maxTokensBeforeSummary = maxTokensBeforeSummary;\n      this.messagesToKeep = messagesToKeep;\n  }\n\n  @Override\n  public String getName() {\n      return "message_summarization";\n  }\n\n  @Override\n  public AgentCommand beforeModel(List<Message> previousMessages, RunnableConfig config) {\n      // \u4f30\u7b97 token \u6570\u91cf\uff08\u7b80\u5316\u7248\uff09\n      int estimatedTokens = previousMessages.stream()\n          .mapToInt(m -> m.getText().length() / 4)\n          .sum();\n\n      if (estimatedTokens < maxTokensBeforeSummary) {\n          return new AgentCommand(previousMessages);\n      }\n\n      // \u9700\u8981\u603b\u7ed3\n      int messagesToSummarize = previousMessages.size() - messagesToKeep;\n      if (messagesToSummarize <= 0) {\n          return new AgentCommand(previousMessages);\n      }\n\n      List<Message> oldMessages = previousMessages.subList(0, messagesToSummarize);\n      List<Message> recentMessages = previousMessages.subList(messagesToSummarize, previousMessages.size());\n\n      // \u751f\u6210\u6458\u8981\n      String summary = generateSummary(oldMessages);\n\n      // \u521b\u5efa\u6458\u8981\u6d88\u606f\n      SystemMessage summaryMessage = new SystemMessage(\n          "## \u4e4b\u524d\u5bf9\u8bdd\u6458\u8981:\n" + summary\n      );\n\n      // \u6784\u5efa\u65b0\u7684\u6d88\u606f\u5217\u8868\uff1a\u6458\u8981\u6d88\u606f + \u4fdd\u7559\u7684\u6700\u8fd1\u6d88\u606f\n      List<Message> newMessages = new ArrayList<>();\n      newMessages.add(summaryMessage);\n      newMessages.addAll(recentMessages);\n\n      // \u4f7f\u7528 REPLACE \u7b56\u7565\u66ff\u6362\u6d88\u606f\u5217\u8868\n      return new AgentCommand(newMessages, UpdatePolicy.REPLACE);\n  }\n\n  private String generateSummary(List<Message> messages) {\n      StringBuilder conversation = new StringBuilder();\n      for (Message msg : messages) {\n          conversation.append(msg.getMessageType())\n                    .append(": ")\n                    .append(msg.getText())\n                    .append("\n");\n      }\n\n      String summaryPrompt = "\u8bf7\u7b80\u8981\u603b\u7ed3\u4ee5\u4e0b\u5bf9\u8bdd:\n\n" + conversation;\n\n      ChatResponse response = summaryModel.call(\n          new Prompt(new UserMessage(summaryPrompt))\n      );\n\n      return response.getResult().getOutput().getText();\n  }\n}\n\n// \u4f7f\u7528\nChatModel summaryModel = // ... \u7528\u4e8e\u603b\u7ed3\u7684\u6a21\u578b\uff08\u53ef\u4ee5\u662f\u66f4\u4fbf\u5b9c\u7684\u6a21\u578b\uff09\n\nMessageSummarizationHook summarizationHook = new MessageSummarizationHook(\n  summaryModel,\n  4000,  // \u5728 4000 tokens \u65f6\u89e6\u53d1\u603b\u7ed3\n  20     // \u603b\u7ed3\u540e\u4fdd\u7559\u6700\u540e 20 \u6761\u6d88\u606f\n);\n\nReactAgent agent = ReactAgent.builder()\n  .name("my_agent")\n  .model(chatModel)\n  .hooks(summarizationHook)\n  .saver(new MemorySaver())\n  .build();\n\nRunnableConfig config = RunnableConfig.builder()\n  .threadId("1")\n  .build();\n\nagent.call("\u4f60\u597d\uff0c\u6211\u53eb bob", config);\nagent.call("\u5199\u4e00\u9996\u5173\u4e8e\u732b\u7684\u77ed\u8bd7", config);\nagent.call("\u73b0\u5728\u5bf9\u72d7\u505a\u540c\u6837\u7684\u4e8b\u60c5", config);\nAssistantMessage finalResponse = agent.call("\u6211\u53eb\u4ec0\u4e48\u540d\u5b57\uff1f", config);\n\nSystem.out.println(finalResponse.getText());\n// \u8f93\u51fa\uff1a\u4f60\u7684\u540d\u5b57\u662f Bob\uff01'}),"\n",(0,o.jsx)(n.h2,{id:"\u8bbf\u95ee\u8bb0\u5fc6",children:"\u8bbf\u95ee\u8bb0\u5fc6"}),"\n",(0,o.jsx)(n.p,{children:"\u4f60\u53ef\u4ee5\u901a\u8fc7\u591a\u79cd\u65b9\u5f0f\u8bbf\u95ee\u548c\u4fee\u6539 Agent \u7684\u77ed\u671f\u8bb0\u5fc6\uff08\u72b6\u6001\uff09\uff1a"}),"\n",(0,o.jsx)(n.h3,{id:"\u5de5\u5177",children:"\u5de5\u5177"}),"\n",(0,o.jsx)(n.h4,{id:"\u5728\u5de5\u5177\u4e2d\u8bfb\u53d6\u77ed\u671f\u8bb0\u5fc6",children:"\u5728\u5de5\u5177\u4e2d\u8bfb\u53d6\u77ed\u671f\u8bb0\u5fc6"}),"\n",(0,o.jsxs)(n.p,{children:["\u4f7f\u7528 ",(0,o.jsx)(n.code,{children:"ToolContext"})," \u53c2\u6570\u5728\u5de5\u5177\u4e2d\u8bbf\u95ee\u77ed\u671f\u8bb0\u5fc6\uff08\u72b6\u6001\uff09\u3002"]}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"toolContext"})," \u53c2\u6570\u4ece\u5de5\u5177\u7b7e\u540d\u4e2d\u9690\u85cf\uff08\u56e0\u6b64\u6a21\u578b\u770b\u4e0d\u5230\u5b83\uff09\uff0c\u4f46\u5de5\u5177\u53ef\u4ee5\u901a\u8fc7\u5b83\u8bbf\u95ee\u72b6\u6001\u3002"]}),"\n",(0,o.jsx)(a,{language:"java",title:"\u5728\u5de5\u5177\u4e2d\u8bfb\u53d6\u77ed\u671f\u8bb0\u5fc6\u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import 
1com.alibaba.cloud.ai.graph.RunnableConfig;\nimport org.springframework.ai.tool.ToolCallback;\nimport org.springframework.ai.tool.function.FunctionToolCallback;\nimport org.springframework.ai.chat.model.ToolContext;\nimport org.springframework.ai.chat.messages.AssistantMessage;\nimport com.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;\nimport java.util.function.BiFunction;\n\npublic class UserInfoTool implements BiFunction<String, ToolContext, String> {\n\n  @Override\n  public String apply(String query, ToolContext toolContext) {\n      // \u4ece\u4e0a\u4e0b\u6587\u4e2d\u83b7\u53d6\u7528\u6237\u4fe1\u606f\n      RunnableConfig config = (RunnableConfig) toolContext.getContext().get("config");\n      String userId = (String) config.metadata("user_id").orElse("");\n\n      if ("user_123".equals(userId)) {\n          return "\u7528\u6237\u662f John Smith";\n      } else {\n          return "\u672a\u77e5\u7528\u6237";\n      }\n  }\n}\n\n// \u521b\u5efa\u5de5\u5177\nToolCallback getUserInfoTool = FunctionToolCallback\n  .builder("get_user_info", new UserInfoTool())\n  .description("\u67e5\u627e\u7528\u6237\u4fe1\u606f")\n  .inputType(String.class)\n  .build();\n\n// \u4f7f\u7528\nReactAgent agent = ReactAgent.builder()\n  .name("my_agent")\n  .model(chatModel)\n  .tools(getUserInfoTool)\n  .saver(new MemorySaver())\n  .build();\n\nRunnableConfig config = RunnableConfig.builder()\n  .threadId("1")\n  .addMetadata("user_id", "user_123")\n  .build();\n\nAssistantMessage response = agent.call("\u83b7\u53d6\u7528\u6237\u4fe1\u606f", config);\nSystem.out.println(response.getText());'}),"\n",(0,o.jsx)(n.h4,{id:"\u4ece\u5de5\u5177\u5199\u5165\u77ed\u671f\u8bb0\u5fc6",children:"\u4ece\u5de5\u5177\u5199\u5165\u77ed\u671f\u8bb0\u5fc6"}),"\n",(0,o.jsx)(n.p,{children:"\u8981\u5728\u6267\u884c\u671f\u95f4\u4fee\u6539 Agent \u7684\u77ed\u671f\u8bb0\u5fc6\uff08\u72b6\u6001\uff09\uff0c\u4f60\u53ef\u4ee5\u5728 Hook \u4e2d\u66f4\u65b0\u72b6\u6001\uff0c\u6216\u8005\u4f7f\u7528\u5de5\u5177\u8fd4\u56de\u7684\u4fe1\u606f\u66f4\u65b0\u72b6\u6001\u3002"}),"\n",(0,o.jsx)(n.p,{children:"\u8fd9\u5bf9\u4e8e\u6301\u4e45\u5316\u4e2d\u95f4\u7ed3\u679c\u6216\u4f7f\u4fe1\u606f\u5bf9\u540e\u7eed\u5de5\u5177\u6216\u63d0\u793a\u53ef\u8bbf\u95ee\u5f88\u6709\u7528\u3002"}),"\n",(0,o.jsx)(n.h3,{id:"\u63d0\u793a",children:"\u63d0\u793a"}),"\n",(0,o.jsx)(n.p,{children:"\u5728 Hook \u4e2d\u8bbf\u95ee\u77ed\u671f\u8bb0\u5fc6\uff08\u72b6\u6001\uff09\u4ee5\u57fa\u4e8e\u5bf9\u8bdd\u5386\u53f2\u6216\u81ea\u5b9a\u4e49\u72b6\u6001\u5b57\u6bb5\u521b\u5efa\u52a8\u6001\u63d0\u793a\u3002"}),"\n",(0,o.jsx)(a,{language:"java",title:"DynamicPromptInterceptor \u52a8\u6001\u63d0\u793a\u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import com.alibaba.cloud.ai.graph.agent.interceptor.ModelInterceptor;\nimport com.alibaba.cloud.ai.graph.agent.interceptor.ModelRequest;\nimport com.alibaba.cloud.ai.graph.agent.interceptor.ModelResponse;\nimport com.alibaba.cloud.ai.graph.agent.interceptor.ModelCallHandler;\n\npublic class DynamicPromptInterceptor extends ModelInterceptor {\n\n  @Override\n  public ModelResponse interceptModel(ModelRequest request, ModelCallHandler handler) {\n      // \u4ece\u4e0a\u4e0b\u6587\u4e2d\u83b7\u53d6\u7528\u6237\u540d\n      Map<String, Object> context = request.getContext();\n      String userName = (String) context.get("user_name");\n\n      // \u521b\u5efa\u52a8\u6001\u7cfb\u7edf\u63d0\u793a\n      String systemPrompt = "\u4f60\u662f\u4e00\u4e2a\u6709\u5e2e\u52a9\u7684\u52a9\u624b\u3002\u79f0\u547c\u7528\u6237\u4e3a " + userName + "\u3002";\n\n      // \u521b\u5efa\u4fee\u6539\u540e\u7684\u8bf7\u6c42\uff08\u793a\u4f8b\uff09\uff0c\u5b9e\u9645\u4f7f\u7528\u4e2d\u9700\u8981\u6839\u636e\u5177\u4f53 API \u8fdb\u884c\u8c03\u6574\n\tSystemMessage enhancedSystemMessage;\n\tif (request.getSystemMessage() == null) {\n\t\tenhancedSystemMessage = new SystemMessage(systemPrompt);\n\t} else {\n\t\tenhancedSystemMessage = new SystemMessage(request.getSystemMessage().getText() + "\n\n" + systemPrompt);\n\t}\n\n\t// Create enhanced request\n\tModelRequest enhancedRequest = ModelRequest.builder(request)\n\t\t\t.systemMessage(enhancedSystemMessage)\n\t\t\t.build();\n\n      return handler.call(enhancedRequest);\n  }\n\n  @Override\n  public String getName() {\n      return "DynamicPromptInterceptor";\n  }\n}\n\nReactAgent agent = ReactAgent.builder()\n  .name("my_agent")\n  .model(chatModel)\n  .tools(getWeatherTool)\n  .interceptors(new DynamicPromptInterceptor())\n  .build();\n\n// \u4f7f\u7528\u65f6\u4f20\u9012\u4e0a\u4e0b\u6587\nMap<String, Object> context = Map.of("user_name", "John Smith");'}),"\n",(0,o.jsx)(n.h3,{id:"before-model",children:"Before Model"}),"\n",(0,o.jsxs)(n.p,{children:["\u5728 ",(0,o.jsx)(n.code,{children:"beforeModel"})," Hook \u4e2d\u8bbf\u95ee\u77ed\u671f\u8bb0\u5fc6\uff08\u72b6\u6001\uff09\u4ee5\u5728\u6a21\u578b\u8c03\u7528\u4e4b\u524d\u5904\u7406\u6d88\u606f\u3002"]}),"\n",(0,o.jsx)(a,{language:"java",title:"TrimMessagesHook Before Model \u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import 
1com.alibaba.cloud.ai.graph.agent.hook.HookPosition;\nimport com.alibaba.cloud.ai.graph.agent.hook.HookPositions;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.MessagesModelHook;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.AgentCommand;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.UpdatePolicy;\nimport com.alibaba.cloud.ai.graph.RunnableConfig;\nimport org.springframework.ai.chat.messages.Message;\nimport java.util.ArrayList;\nimport java.util.List;\n\n@HookPositions({HookPosition.BEFORE_MODEL})\npublic class TrimMessagesHook extends MessagesModelHook {\n\n  @Override\n  public String getName() {\n      return "trim_messages";\n  }\n\n  @Override\n  public AgentCommand beforeModel(List<Message> previousMessages, RunnableConfig config) {\n      if (previousMessages.size() <= 3) {\n          return new AgentCommand(previousMessages); // \u65e0\u9700\u66f4\u6539\n      }\n\n      // \u4fdd\u7559\u7b2c\u4e00\u6761\u548c\u6700\u540e\u51e0\u6761\u6d88\u606f\n      Message firstMsg = previousMessages.get(0);\n      List<Message> recentMessages = previousMessages.subList(\n          previousMessages.size() - 3,\n          previousMessages.size()\n      );\n\n      List<Message> trimmedMessages = new ArrayList<>();\n      trimmedMessages.add(firstMsg);\n      trimmedMessages.addAll(recentMessages);\n\n      // \u4f7f\u7528 REPLACE \u7b56\u7565\u66ff\u6362\u6d88\u606f\u5217\u8868\uff0c\u53ea\u4fdd\u7559\u9700\u8981\u7684\u6d88\u606f\n      return new AgentCommand(trimmedMessages, UpdatePolicy.REPLACE);\n  }\n}\n\nReactAgent agent = ReactAgent.builder()\n  .name("my_agent")\n  .model(chatModel)\n  .tools(tools)\n  .hooks(new TrimMessagesHook())\n  .saver(new MemorySaver())\n  .build();'}),"\n",(0,o.jsx)(n.h3,{id:"after-model",children:"After Model"}),"\n",(0,o.jsxs)(n.p,{children:["\u5728 ",(0,o.jsx)(n.code,{children:"afterModel"})," Hook \u4e2d\u8bbf\u95ee\u77ed\u671f\u8bb0\u5fc6\uff08\u72b6\u6001\uff09\u4ee5\u5728\u6a21\u578b\u8c03\u7528\u4e4b\u540e\u5904\u7406\u6d88\u606f\u3002"]}),"\n",(0,o.jsx)(a,{language:"java",title:"ValidateResponseHook After Model \u793a\u4f8b",sourceUrl:"https://github.com/alibaba/spring-ai-alibaba/tree/main/examples/documentation/src/main/java/com/alibaba/cloud/ai/examples/documentation/framework/tutorials/MemoryExample.java",children:'import com.alibaba.cloud.ai.graph.agent.hook.HookPosition;\nimport com.alibaba.cloud.ai.graph.agent.hook.HookPositions;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.MessagesModelHook;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.AgentCommand;\nimport com.alibaba.cloud.ai.graph.agent.hook.messages.UpdatePolicy;\nimport com.alibaba.cloud.ai.graph.RunnableConfig;\nimport org.springframework.ai.chat.messages.AssistantMessage;\nimport org.springframework.ai.chat.messages.Message;\nimport java.util.ArrayList;\nimport java.util.List;\n\n@HookPositions({HookPosition.AFTER_MODEL})\npublic class ValidateResponseHook extends MessagesModelHook {\n\n  private static final List<String> STOP_WORDS =\n      List.of("password", "secret", "api_key");\n\n  @Override\n  public String getName() {\n      return "validate_response";\n  }\n\n  @Override\n  public AgentCommand afterModel(List<Message> previousMessages, RunnableConfig config) {\n      if (previousMessages.isEmpty()) {\n          return new AgentCommand(previousMessages);\n      }\n\n      Message lastMessage = previousMessages.get(previousMessages.size() - 1);\n      String content = lastMessage.getText();\n\n      // \u68c0\u67e5\u662f\u5426\u5305\u542b\u654f\u611f\u8bcd\n      for (String stopWord : STOP_WORDS) {\n          if (content.toLowerCase().contains(stopWord)) {\n              // \u79fb\u9664\u5305\u542b\u654f\u611f\u8bcd\u7684\u6d88\u606f\uff0c\u66ff\u6362\u4e3a\u5b89\u5168\u6d88\u606f\n              List<Message> filtered = new ArrayList<>(\n                  previousMessages.subList(0, previousMessages.size() - 1)\n              );\n              filtered.add(new AssistantMessage("\u62b1\u6b49\uff0c\u6211\u65e0\u6cd5\u63d0\u4f9b\u8be5\u4fe1\u606f\u3002"));\n              return new AgentCommand(filtered, UpdatePolicy.REPLACE);\n          }\n      }\n\n      return new AgentCommand(previousMessages);\n  }\n}\n\nReactAgent agent = ReactAgent.builder()\n  .name("secure_agent")\n  .model(chatModel)\n  .hooks(new ValidateResponseHook())\n  .saver(new MemorySaver())\n  .build();'}),"\n",(0,o.jsx)(n.h2,{id:"\u76f8\u5173\u8d44\u6e90",children:"\u76f8\u5173\u8d44\u6e90"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"/docs/frameworks/agent-framework/tutorials/agents",children:"Agents \u6587\u6863"})," - \u4e86\u89e3 ReactAgent \u7684\u6838\u5fc3\u6982\u5ff5"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"/docs/frameworks/agent-framework/tutorials/hooks",children:"Hooks \u548c Interceptors"})," - \u4e86\u89e3\u5982\u4f55\u6269\u5c55 Agent \u529f\u80fd"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"/docs/frameworks/agent-framework/tutorials/messages",children:"Messages \u6587\u6863"})," - \u4e86\u89e3\u6d88\u606f\u7c7b\u578b\u548c\u4f7f\u7528"]}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(g,{...e})}):g(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>t,x:()=>r});var s=a(96540);const o={},i=s.createContext(o);function t(e){const n=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.