<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>AI Agent on WY 的技术博客</title><link>https://zhouwy.top/tags/ai-agent/</link><description>Recent content in AI Agent on WY 的技术博客</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Wed, 20 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://zhouwy.top/tags/ai-agent/index.xml" rel="self" type="application/rss+xml"/><item><title>AgentScope Java Harness 架构与实战指南</title><link>https://zhouwy.top/posts/agentscope-java-harness-%E6%9E%B6%E6%9E%84%E4%B8%8E%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97/</link><pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate><guid>https://zhouwy.top/posts/agentscope-java-harness-%E6%9E%B6%E6%9E%84%E4%B8%8E%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;AgentScope Java 的 Harness 模块是一个面向生产环境的多智能体运行时框架。本文基于官方文档，从其设计理念到具体代码实践，完整梳理 Harness 的核心架构与使用方式。&lt;/p&gt;
&lt;h2 id="一harness-是什么"&gt;一、Harness 是什么&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;agentscope-harness&lt;/code&gt; 在 &lt;code&gt;agentscope-core&lt;/code&gt; 的 &lt;code&gt;ReActAgent&lt;/code&gt; 之上，通过 &lt;strong&gt;Hook&lt;/strong&gt; 和 &lt;strong&gt;Toolkit&lt;/strong&gt; 两个扩展点，装配出一套面向长期稳定运行的工程化基础设施。它的入口只有一个类：&lt;code&gt;HarnessAgent&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;裸的 &lt;code&gt;ReActAgent&lt;/code&gt; 只有&amp;quot;请求 — 推理 — 工具 — 回复&amp;quot;一轮循环。而 Harness 要回答的是一组更贴近生产的问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下一轮怎么办？&lt;/li&gt;
&lt;li&gt;下一天怎么办？&lt;/li&gt;
&lt;li&gt;上下文爆了怎么办？&lt;/li&gt;
&lt;li&gt;状态丢了怎么办？&lt;/li&gt;
&lt;li&gt;任务太重怎么办？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它不替换推理循环，而是在循环的关键时机插入 hook、为模型补上一组基础工具，把这些问题的默认工程答案打包好。&lt;/p&gt;
&lt;h3 id="快速开始"&gt;快速开始&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.agentscope&lt;span style="color:#f92672"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;agentscope-harness&lt;span style="color:#f92672"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;${agentscope.version}&lt;span style="color:#f92672"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;QuickstartExample&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; Exception {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 1. 准备工作区&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Path workspace &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Paths.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;.agentscope/workspace&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; initWorkspaceIfAbsent(workspace);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 2. 构建模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Model model &lt;span style="color:#f92672"&gt;=&lt;/span&gt; DashScopeChatModel.&lt;span style="color:#a6e22e"&gt;builder&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;apiKey&lt;/span&gt;(System.&lt;span style="color:#a6e22e"&gt;getenv&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;DASHSCOPE_API_KEY&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;modelName&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;qwen-max&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;build&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 3. 构建 HarnessAgent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HarnessAgent agent &lt;span style="color:#f92672"&gt;=&lt;/span&gt; HarnessAgent.&lt;span style="color:#a6e22e"&gt;builder&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;quickstart-agent&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;sysPrompt&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;你是一个帮助用户做笔记的助手。&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;model&lt;/span&gt;(model)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;workspace&lt;/span&gt;(workspace)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;compaction&lt;/span&gt;(CompactionConfig.&lt;span style="color:#a6e22e"&gt;builder&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;triggerMessages&lt;/span&gt;(30)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;keepMessages&lt;/span&gt;(10)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;flushBeforeCompact&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;build&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;build&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 4. 两轮对话，同一 sessionId&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RuntimeContext ctx &lt;span style="color:#f92672"&gt;=&lt;/span&gt; RuntimeContext.&lt;span style="color:#a6e22e"&gt;builder&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;sessionId&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;demo-session&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;userId&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;alice&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;build&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Msg turn1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; agent.&lt;span style="color:#a6e22e"&gt;call&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Msg.&lt;span style="color:#a6e22e"&gt;builder&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;role&lt;/span&gt;(MsgRole.&lt;span style="color:#a6e22e"&gt;USER&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;textContent&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;我叫天宇，今天准备做一个关于 ReAct 的技术分享。&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;build&lt;/span&gt;(),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ctx).&lt;span style="color:#a6e22e"&gt;block&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Msg turn2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; agent.&lt;span style="color:#a6e22e"&gt;call&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Msg.&lt;span style="color:#a6e22e"&gt;builder&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;role&lt;/span&gt;(MsgRole.&lt;span style="color:#a6e22e"&gt;USER&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;textContent&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;我叫什么？我今天要干什么？&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;build&lt;/span&gt;(),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ctx).&lt;span style="color:#a6e22e"&gt;block&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;initWorkspaceIfAbsent&lt;/span&gt;(Path workspace) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; Exception {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Files.&lt;span style="color:#a6e22e"&gt;createDirectories&lt;/span&gt;(workspace);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Path agentsMd &lt;span style="color:#f92672"&gt;=&lt;/span&gt; workspace.&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;AGENTS.md&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (Files.&lt;span style="color:#a6e22e"&gt;exists&lt;/span&gt;(agentsMd)) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Files.&lt;span style="color:#a6e22e"&gt;writeString&lt;/span&gt;(agentsMd, &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; # 笔记助手
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; 你是一个帮助用户整理笔记和知识的助手。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; ## 行为约定
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; - 主动记录用户提到的关键事实（姓名、计划、偏好等）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; - 回答用简洁中文，必要时给出要点列表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; - 对不确定的内容要主动说明，不要臆造
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上述代码展示了 Harness 的三个核心价值：&lt;strong&gt;工作区驱动的人格&lt;/strong&gt;、&lt;strong&gt;会话持久化&lt;/strong&gt;（同一 sessionId 的第二轮对话记得第一轮的内容）、&lt;strong&gt;显式启用对话压缩&lt;/strong&gt;。&lt;/p&gt;</description></item></channel></rss>