<?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>语义握手 on Agent-Mesh 技术博客</title>
    <link>https://ggrryta.github.io/agent-mesh/zh/tags/%E8%AF%AD%E4%B9%89%E6%8F%A1%E6%89%8B/</link>
    <description>Recent content in 语义握手 on Agent-Mesh 技术博客</description>
    <generator>Hugo</generator>
    <language>zh</language>
    <lastBuildDate>Wed, 20 May 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://ggrryta.github.io/agent-mesh/zh/tags/%E8%AF%AD%E4%B9%89%E6%8F%A1%E6%89%8B/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>语义握手、行为标注、复杂度评估：三个协作质量机制的落地实现</title>
      <link>https://ggrryta.github.io/agent-mesh/zh/posts/collaboration-quality-mechanisms/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://ggrryta.github.io/agent-mesh/zh/posts/collaboration-quality-mechanisms/</guid>
      <description>从博客里的设计原则到代码落地——复杂度评估、语义握手协议、行为标注三个机制如何在 Agent Mesh 中实现，以及我们做出的工程取舍。</description>
      <content:encoded><![CDATA[<blockquote>
<p>本文是《多 Agent 协作的五个设计原则》的工程续篇。上一篇提出了语义分区、信任机制、协作光谱等理论框架；本文记录这些理论如何变成可运行的代码。</p>
</blockquote>
<hr>
<h2 id="背景从全信到有据可查">背景：从&quot;全信&quot;到&quot;有据可查&quot;</h2>
<p>在实现多 Agent 协作的过程中，我们遇到了一个反复出现的问题：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-5">5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-6">6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-7">7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-8">8</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>用户：&#34;帮我写一个 HTTP server&#34;
</span></span><span style="display:flex;"><span>Alice 委派给 Bob
</span></span><span style="display:flex;"><span>Bob 回复：&#34;写好了，编译通过，在 /tmp/server/main.go&#34;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>问题：
</span></span><span style="display:flex;"><span>  - Bob 真的跑了 go build 吗？还是只是&#34;觉得&#34;能编译？
</span></span><span style="display:flex;"><span>  - Alice 怎么判断这个回复可信？
</span></span><span style="display:flex;"><span>  - 用户怎么知道这个结果经过了验证？
</span></span></code></pre></td></tr></table>
</div>
</div><p>之前的模式是&quot;全信&quot;——收到就用，不验证。这在简单任务中可行，但在复杂协作中会导致错误累积：A 基于 B 的未验证结论做决策，C 又基于 A 的决策继续推进，最终发现源头就是错的。</p>
<p>我们需要三个机制来管理协作质量：</p>
<ol>
<li><strong>复杂度评估</strong>——决定一个任务需要多少&quot;仪式感&quot;</li>
<li><strong>语义握手</strong>——执行前对齐理解，减少返工</li>
<li><strong>行为标注</strong>——让每条回复的可信度可见</li>
</ol>
<hr>
<h2 id="机制一复杂度评估">机制一：复杂度评估</h2>
<h3 id="设计决策">设计决策</h3>
<p>第一个问题是：谁来评估复杂度？</p>
<table>
  <thead>
      <tr>
          <th>方案</th>
          <th>优点</th>
          <th>缺点</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>LLM 评估</td>
          <td>理解语义</td>
          <td>贵、慢、不确定</td>
      </tr>
      <tr>
          <td>发送方指定</td>
          <td>零成本、最准确</td>
          <td>依赖发送方判断</td>
      </tr>
      <tr>
          <td>规则推断</td>
          <td>确定性、零成本</td>
          <td>粗糙</td>
      </tr>
  </tbody>
</table>
<p>我们选了<strong>发送方指定 + 规则兜底</strong>的组合。</p>
<h3 id="实现">实现</h3>
<p><code>mesh_send_message</code> 和 <code>mesh_broadcast</code> 新增可选的 <code>complexity</code> 参数：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-5">5</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#a6e22e">mesh_send_message</span>(
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">to_agent_id</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#34;bob-coder@example&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">text</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#34;重构 task 模块的状态机逻辑，抽到独立文件&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">complexity</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#34;high&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></td></tr></table>
</div>
</div><p>发送方不指定时，启发式规则自动推断：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-5">5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-6">6</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">inferComplexity</span>(<span style="color:#a6e22e">text</span>: <span style="color:#66d9ef">string</span>)<span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;low&#39;</span> <span style="color:#f92672">|</span> <span style="color:#e6db74">&#39;medium&#39;</span> <span style="color:#f92672">|</span> <span style="color:#e6db74">&#39;high&#39;</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">highSignals</span> <span style="color:#f92672">=</span> [<span style="color:#e6db74">&#39;重构&#39;</span>, <span style="color:#e6db74">&#39;架构&#39;</span>, <span style="color:#e6db74">&#39;设计&#39;</span>, <span style="color:#e6db74">&#39;迁移&#39;</span>, <span style="color:#e6db74">&#39;从零&#39;</span>, <span style="color:#e6db74">&#39;全面&#39;</span>, <span style="color:#e6db74">&#39;系统性&#39;</span>, <span style="color:#e6db74">&#39;多模块&#39;</span>]
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">highSignals</span>.<span style="color:#a6e22e">some</span>(<span style="color:#a6e22e">s</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">text</span>.<span style="color:#a6e22e">includes</span>(<span style="color:#a6e22e">s</span>))) <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#39;high&#39;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">text</span>.<span style="color:#a6e22e">length</span> <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">200</span> <span style="color:#f92672">||</span> <span style="color:#a6e22e">text</span>.<span style="color:#a6e22e">includes</span>(<span style="color:#e6db74">&#39;步骤&#39;</span>) <span style="color:#f92672">||</span> <span style="color:#a6e22e">text</span>.<span style="color:#a6e22e">includes</span>(<span style="color:#e6db74">&#39;然后&#39;</span>)) <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#39;medium&#39;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#39;low&#39;</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>复杂度通过消息的 metadata part 传递给接收方：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-4">4</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#a6e22e">parts</span><span style="color:#f92672">:</span> [
</span></span><span style="display:flex;"><span>  { <span style="color:#a6e22e">kind</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;text&#39;</span>, <span style="color:#a6e22e">text</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;重构 task 模块...&#39;</span> },
</span></span><span style="display:flex;"><span>  { <span style="color:#a6e22e">kind</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;metadata&#39;</span>, <span style="color:#a6e22e">key</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;complexity&#39;</span>, <span style="color:#a6e22e">value</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;high&#39;</span> }
</span></span><span style="display:flex;"><span>]
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="工程取舍">工程取舍</h3>
<p>规则推断很粗糙——&ldquo;重构&quot;一定是 high 吗？&ldquo;然后&quot;一定意味着多步骤吗？不一定。但这个粗糙是有意为之的：</p>
<ul>
<li>它是<strong>兜底</strong>，不是主力。大部分情况下发送方（Alice）会根据自己的判断显式指定</li>
<li>误判的代价很低——把 low 误判为 medium 只是多了一步确认，不会造成错误</li>
<li>规则可以随时调整，不需要重新训练模型</li>
</ul>
<hr>
<h2 id="机制二语义握手">机制二：语义握手</h2>
<h3 id="设计决策-1">设计决策</h3>
<p>语义握手的核心问题是：<strong>怎么让 agent 在执行前先确认理解？</strong></p>
<p>我们考虑了三种方案：</p>
<table>
  <thead>
      <tr>
          <th>方案</th>
          <th>可靠性</th>
          <th>复杂度</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>纯 prompt 引导</td>
          <td>低（LLM 可能跳过）</td>
          <td>低</td>
      </tr>
      <tr>
          <td>状态机强制阻断</td>
          <td>高（代码保证）</td>
          <td>高</td>
      </tr>
      <tr>
          <td>双层组合</td>
          <td>中高</td>
          <td>中</td>
      </tr>
  </tbody>
</table>
<p>纯 prompt 不够可靠——agent 可能直接跳过确认步骤开始执行。状态机强制阻断太复杂——需要判断&quot;这条回复是确认理解还是执行结果&rdquo;，这本身又需要 LLM。</p>
<p>我们选了<strong>双层组合</strong>：system prompt 教 agent 自主判断 + runtime 对标记了 complexity 的消息强制注入引导。</p>
<h3 id="实现-1">实现</h3>
<p><strong>第一层：system prompt 里的自主判断</strong></p>
<p>所有 agent 共享的 meshSystemGuide 里写明：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-5">5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-6">6</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>语义握手（收到任务时的自主判断）：
</span></span><span style="display:flex;"><span>  收到一个新任务时，先评估是否需要确认理解再执行：
</span></span><span style="display:flex;"><span>  - 任务有歧义（&#34;优化这个服务&#34;——优化什么？延迟？内存？吞吐？）→ 先确认
</span></span><span style="display:flex;"><span>  - 任务涉及多步骤或多文件 → 先确认方案
</span></span><span style="display:flex;"><span>  - 任务有隐含假设（&#34;部署到生产&#34;——要不要先跑测试？）→ 先列出假设让对方确认
</span></span><span style="display:flex;"><span>  - 任务很简单明确（&#34;查一下版本号&#34;）→ 直接执行，不需要确认
</span></span></code></pre></td></tr></table>
</div>
</div><p>这层靠 agent 自己判断——即使发送方没标记 complexity，agent 也可能主动触发握手。</p>
<p><strong>第二层：runtime 注入的强引导</strong></p>
<p>当消息携带 <code>complexity=medium/high</code> 元数据时，<code>formatEventAsPrompt</code> 生成不同的引导语：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-12">12</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">complexity</span> <span style="color:#f92672">===</span> <span style="color:#e6db74">&#39;high&#39;</span> <span style="color:#f92672">||</span> <span style="color:#a6e22e">complexity</span> <span style="color:#f92672">===</span> <span style="color:#e6db74">&#39;medium&#39;</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">lines</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`⚠️ 这是一个</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">complexity</span> <span style="color:#f92672">===</span> <span style="color:#e6db74">&#39;high&#39;</span> <span style="color:#f92672">?</span> <span style="color:#e6db74">&#39;高&#39;</span> <span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;中等&#39;</span><span style="color:#e6db74">}</span><span style="color:#e6db74">复杂度任务，请先确认你的理解再执行：`</span>)
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">lines</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`1. 用 mesh_reply 回复你理解的范围、方法和假设`</span>)
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">lines</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`2. 等对方确认后再动手执行`</span>)
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">lines</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`3. 如果有疑问，在回复中列出`</span>)
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">lines</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">``</span>)
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">lines</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`回复格式参考：`</span>)
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">lines</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`  范围：...`</span>)
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">lines</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`  方法：...`</span>)
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">lines</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`  假设：...`</span>)
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">lines</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`  疑问：...`</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="实际效果">实际效果</h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-16">16</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>Alice → Bob（complexity=high）：
</span></span><span style="display:flex;"><span>  &#34;重构 task 模块，把状态机逻辑从 service.go 抽到独立的 fsm.go&#34;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Bob 收到的 prompt：
</span></span><span style="display:flex;"><span>  ⚠️ 这是一个高复杂度任务，请先确认你的理解再执行...
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Bob 回复：
</span></span><span style="display:flex;"><span>  范围：把 Transition()、IsAllowedTransition()、allowedTransitions map 抽到 fsm.go
</span></span><span style="display:flex;"><span>  方法：新建 fsm.go，移动函数，service.go 改为调用 fsm 包
</span></span><span style="display:flex;"><span>  假设：不改 Service 的公开 API，只是内部重组
</span></span><span style="display:flex;"><span>  疑问：状态常量（StateSubmitted 等）也移过去吗？
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Alice 确认：
</span></span><span style="display:flex;"><span>  确认。状态常量也移过去，fsm.go 包含完整的状态机定义。
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Bob 开始执行。
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="工程取舍-1">工程取舍</h3>
<p>这不是硬性阻断——Bob 如果判断任务很清晰，可以跳过握手直接执行。我们接受这个&quot;漏洞&rdquo;，因为：</p>
<ul>
<li>硬性阻断需要判断&quot;回复是确认还是执行结果&quot;——这个判断本身不可靠</li>
<li>大部分情况下 ⚠️ 标记 + 具体格式要求足以引导 agent 遵守</li>
<li>偶尔跳过的代价是&quot;可能返工&quot;，不是&quot;系统崩溃&quot;</li>
</ul>
<hr>
<h2 id="机制三行为标注">机制三：行为标注</h2>
<h3 id="设计决策-2">设计决策</h3>
<p>博客里提出了&quot;信任不能自证&quot;的原则——不能让 agent 自己评估自己的可信度。那怎么标注？</p>
<p>我们的答案是：<strong>不问 agent 它有没有验证，而是观察它实际做了什么，然后 runtime 独立确认。</strong></p>
<p>三层标注：</p>
<table>
  <thead>
      <tr>
          <th>层级</th>
          <th>标注</th>
          <th>含义</th>
          <th>可信度</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>独立验证 ✓</td>
          <td><code>[独立验证 ✓]</code></td>
          <td>runtime 自己确认了事实</td>
          <td>最高</td>
      </tr>
      <tr>
          <td>agent 已验证</td>
          <td><code>[agent 已验证]</code></td>
          <td>agent 调了验证工具（但 runtime 没独立确认）</td>
          <td>中</td>
      </tr>
      <tr>
          <td>未验证</td>
          <td><code>[未验证]</code></td>
          <td>纯推理，无任何验证</td>
          <td>低</td>
      </tr>
  </tbody>
</table>
<h3 id="实现-2">实现</h3>
<p><strong>第一层：prompt 引导（验证清单）</strong></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-5">5</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>验证清单（完成编码任务后必须执行）：
</span></span><span style="display:flex;"><span>  □ 文件已创建/修改 → 用 Read 确认文件内容正确
</span></span><span style="display:flex;"><span>  □ 编译通过 → 用 Bash 跑 go build 或 bun build
</span></span><span style="display:flex;"><span>  □ 基本功能正确 → 用 Bash 跑 go test 或 go run
</span></span><span style="display:flex;"><span>  注意：系统会自动检测你是否执行了验证，并在回复末尾追加标注。
</span></span></code></pre></td></tr></table>
</div>
</div><p>最后一句&quot;系统会自动检测&quot;形成心理压力——agent 知道自己的行为会被审计。</p>
<p><strong>第二层：PostToolUse Hook（精确行为观察）</strong></p>
<p>通过 Claude SDK 的 <code>hooks.PostToolUse</code> 拦截工具执行结果，拿到完整的 exit code：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-16">16</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#a6e22e">hooks</span><span style="color:#f92672">:</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">PostToolUse</span><span style="color:#f92672">:</span> [{
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">hooks</span><span style="color:#f92672">:</span> [<span style="color:#66d9ef">async</span> (<span style="color:#a6e22e">event</span>) <span style="color:#f92672">=&gt;</span> {
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">toolName</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">event</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">tool_name</span> <span style="color:#f92672">||</span> <span style="color:#e6db74">&#39;&#39;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">exitCode</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">event</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">tool_result</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">exit_code</span>
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">cmd</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">event</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">tool_input</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">command</span> <span style="color:#f92672">||</span> <span style="color:#e6db74">&#39;&#39;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">toolName</span> <span style="color:#f92672">===</span> <span style="color:#e6db74">&#39;Bash&#39;</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">exitCode</span> <span style="color:#f92672">===</span> <span style="color:#ae81ff">0</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">cmd</span>.<span style="color:#a6e22e">includes</span>(<span style="color:#e6db74">&#39;go build&#39;</span>)) <span style="color:#a6e22e">turnCtx</span>.<span style="color:#a6e22e">verifications</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">&#39;编译通过(exit 0)&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">cmd</span>.<span style="color:#a6e22e">includes</span>(<span style="color:#e6db74">&#39;go test&#39;</span>)) <span style="color:#a6e22e">turnCtx</span>.<span style="color:#a6e22e">verifications</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">&#39;测试通过(exit 0)&#39;</span>)
</span></span><span style="display:flex;"><span>      } <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">toolName</span> <span style="color:#f92672">===</span> <span style="color:#e6db74">&#39;Bash&#39;</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">exitCode</span> <span style="color:#f92672">!==</span> <span style="color:#66d9ef">undefined</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">exitCode</span> <span style="color:#f92672">!==</span> <span style="color:#ae81ff">0</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">turnCtx</span>.<span style="color:#a6e22e">verifications</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`命令失败(exit </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">exitCode</span><span style="color:#e6db74">}</span><span style="color:#e6db74">): </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">cmd</span>.<span style="color:#a6e22e">slice</span>(<span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">50</span>)<span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>)
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">return</span> { <span style="color:#66d9ef">continue</span><span style="color:#f92672">:</span> <span style="color:#66d9ef">true</span> }
</span></span><span style="display:flex;"><span>    }],
</span></span><span style="display:flex;"><span>  }],
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>相比之前只看 <code>tool_use</code> 块（只知道&quot;调没调&quot;），PostToolUse hook 能区分&quot;调了且成功&quot;和&quot;调了但失败&quot;——标注精度大幅提升。</p>
<p><strong>第三层：事后独立验证</strong></p>
<p><code>mesh_reply</code> 发送前，runtime 扫描回复文本中的可验证声明，自己确认：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-21">21</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#66d9ef">async</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">runIndependentVerification</span>(<span style="color:#a6e22e">replyText</span>: <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">cwd</span>: <span style="color:#66d9ef">string</span>)<span style="color:#f92672">:</span> <span style="color:#a6e22e">Promise</span>&lt;<span style="color:#f92672">string</span><span style="color:#960050;background-color:#1e0010">[]</span>&gt; {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">results</span>: <span style="color:#66d9ef">string</span>[] <span style="color:#f92672">=</span> []
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">// 检测&#34;创建了 xxx.go&#34; → stat 确认文件存在
</span></span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">filePathPattern</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">/(?:创建|写入|生成).*?([/\w.\-@]+\.\w{1,5})/g</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">// ... 对每个匹配的路径执行 stat
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">// 检测&#34;编译通过&#34; → 跑 go build 确认
</span></span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">replyText</span>.<span style="color:#a6e22e">includes</span>(<span style="color:#e6db74">&#39;编译通过&#39;</span>)) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">execAsync</span>(<span style="color:#e6db74">&#39;go build ./...&#39;</span>, { <span style="color:#a6e22e">cwd</span>, <span style="color:#a6e22e">timeout</span>: <span style="color:#66d9ef">15000</span> })
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">results</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">&#39;编译通过&#39;</span>)
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">// 检测&#34;测试通过&#34; → 跑 go test 确认
</span></span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">replyText</span>.<span style="color:#a6e22e">includes</span>(<span style="color:#e6db74">&#39;测试通过&#39;</span>)) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">execAsync</span>(<span style="color:#e6db74">&#39;go test ./...&#39;</span>, { <span style="color:#a6e22e">cwd</span>, <span style="color:#a6e22e">timeout</span>: <span style="color:#66d9ef">30000</span> })
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">results</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">&#39;测试通过&#39;</span>)
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">results</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>标注组合逻辑</strong>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-12">12</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">independentResults</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">runIndependentVerification</span>(<span style="color:#a6e22e">args</span>.<span style="color:#a6e22e">text</span>, <span style="color:#a6e22e">turnCtx</span>.<span style="color:#a6e22e">cwd</span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">agentVerified</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">turnCtx</span>.<span style="color:#a6e22e">verifications</span>.<span style="color:#a6e22e">length</span> <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">independentResults</span>.<span style="color:#a6e22e">length</span> <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">0</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">annotations</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`[独立验证 ✓] </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">independentResults</span>.<span style="color:#a6e22e">join</span>(<span style="color:#e6db74">&#39;、&#39;</span>)<span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">agentVerified</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">annotations</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">`[agent 已验证] </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">remaining</span>.<span style="color:#a6e22e">join</span>(<span style="color:#e6db74">&#39;、&#39;</span>)<span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">annotations</span>.<span style="color:#a6e22e">length</span> <span style="color:#f92672">===</span> <span style="color:#ae81ff">0</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">annotations</span>.<span style="color:#a6e22e">push</span>(<span style="color:#e6db74">&#39;[未验证] 以上结论基于推理，未执行验证命令&#39;</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="实际效果-1">实际效果</h3>
<p><strong>Bob 写了代码并验证成功</strong>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-4">4</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>hello.go 已创建，编译通过，可以直接 go run。
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>[独立验证 ✓] 文件存在: hello.go、编译通过
</span></span><span style="display:flex;"><span>[agent 已验证] 编译通过(exit 0)、运行成功(exit 0)
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Bob 跑了命令但失败了</strong>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-3">3</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>代码写好了，但编译有个小问题，我来修一下。
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>[agent 已验证] 命令失败(exit 1): go build ./...
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Bob 只是给了建议</strong>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-13-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-13-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-13-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-13-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-13-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-13-3">3</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>建议把查询改成批量接口，预计能降低 60% 的延迟。
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>[未验证] 以上结论基于推理，未执行验证命令
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="工程取舍-2">工程取舍</h3>
<ol>
<li>
<p><strong>独立验证只做低成本操作</strong>——stat 文件（&lt;1ms）、go build（&lt;5s）。不会跑完整的集成测试或性能测试。</p>
</li>
<li>
<p><strong>关键词匹配不完美</strong>——&ldquo;编译通过&quot;的检测靠字符串匹配，agent 如果说&quot;build 成功了&quot;可能匹配不到。但这是可以持续补充的规则集。</p>
</li>
<li>
<p><strong>标注是强制追加的</strong>——agent 无法删除或伪造标注。它写的 <code>text</code> 参数会被 runtime 在末尾拼接标注后再发送。这是&quot;外部赋予信任&quot;的具体体现。</p>
</li>
</ol>
<hr>
<h2 id="三个机制的协同">三个机制的协同</h2>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-17">17</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>用户发任务给 Alice
</span></span><span style="display:flex;"><span>    │
</span></span><span style="display:flex;"><span>    ▼
</span></span><span style="display:flex;"><span>Alice 评估复杂度（显式指定或启发式推断）
</span></span><span style="display:flex;"><span>    │
</span></span><span style="display:flex;"><span>    ├── low → effort=low, thinking=disabled
</span></span><span style="display:flex;"><span>    │         直接委派 Bob，Bob 执行后回复带行为标注
</span></span><span style="display:flex;"><span>    │
</span></span><span style="display:flex;"><span>    ├── medium → effort=medium, thinking=adaptive
</span></span><span style="display:flex;"><span>    │            语义握手（Bob 先确认理解）→ 执行 → 行为标注
</span></span><span style="display:flex;"><span>    │
</span></span><span style="display:flex;"><span>    └── high → effort=high, thinking=adaptive
</span></span><span style="display:flex;"><span>               语义握手 → 执行 → 行为标注 → Alice 自己也验证
</span></span><span style="display:flex;"><span>                                                → 双重标注
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>全程硬性防护：maxTurns=30, maxBudgetUsd=$5
</span></span><span style="display:flex;"><span>PostToolUse hook 实时记录每个工具调用的成功/失败
</span></span></code></pre></td></tr></table>
</div>
</div><p>三个机制不是独立的——复杂度同时决定三件事：是否触发握手、推理深度多少、验证要求多严格。</p>
<hr>
<h2 id="与博客理论的对应">与博客理论的对应</h2>
<table>
  <thead>
      <tr>
          <th>博客原则</th>
          <th>落地实现</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>语义分区不能解决，只能管理</td>
          <td>语义握手让隐含假设显式化</td>
      </tr>
      <tr>
          <td>信任 = 锚点密度</td>
          <td>行为标注的三级就是锚点密度的具象化</td>
      </tr>
      <tr>
          <td>信任不能自证</td>
          <td>标注基于行为观察 + 独立验证，不问 agent 自评</td>
      </tr>
      <tr>
          <td>复杂度评估前置</td>
          <td>complexity 参数 + 启发式推断</td>
      </tr>
      <tr>
          <td>纵深防御</td>
          <td>prompt 引导 + 行为观察 + 独立验证，三层叠加</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="已知局限和后续方向">已知局限和后续方向</h2>
<ol>
<li>
<p><strong>语义握手不是硬性阻断</strong>——agent 可以跳过。后续可以加状态机：收到 high 任务后标记为 <code>awaiting_confirmation</code>，只有收到确认后才允许执行。</p>
</li>
<li>
<p><strong>独立验证只覆盖&quot;文件存在&quot;和&quot;编译通过&rdquo;</strong>——更复杂的验证（逻辑正确性、性能达标）需要更多规则或引入专门的验证 agent。</p>
</li>
<li>
<p><strong>规则匹配是脆弱的</strong>——&ldquo;编译通过&quot;的检测靠关键词，换个说法就匹配不到。后续可以用轻量 LLM 做声明提取，但会增加成本和延迟。</p>
</li>
</ol>
<p>这些局限是有意识的工程取舍——先用低成本方案覆盖 80% 的场景，再根据实际数据决定哪些地方值得投入更多。</p>
<hr>
<h2 id="附sdk-级别的资源管控">附：SDK 级别的资源管控</h2>
<p>除了协作质量机制，我们还利用 Claude SDK 的原生能力做了资源管控：</p>
<h3 id="推理深度随复杂度自适应">推理深度随复杂度自适应</h3>
<p>复杂度评估不只影响语义握手——它还直接控制 LLM 的推理深度：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-5">5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-6">6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-7">7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-8">8</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#75715e">// low complexity → 快速响应，省 token
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">effort</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;low&#39;</span>, <span style="color:#a6e22e">thinking</span><span style="color:#f92672">:</span> { <span style="color:#66d9ef">type</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;disabled&#39;</span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// medium complexity → 适度推理
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">effort</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;medium&#39;</span>, <span style="color:#a6e22e">thinking</span><span style="color:#f92672">:</span> { <span style="color:#66d9ef">type</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;adaptive&#39;</span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// high complexity → 深度推理，质量优先
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">effort</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;high&#39;</span>, <span style="color:#a6e22e">thinking</span><span style="color:#f92672">:</span> { <span style="color:#66d9ef">type</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;adaptive&#39;</span> }
</span></span></code></pre></td></tr></table>
</div>
</div><p>简单任务（&ldquo;查一下版本号&rdquo;）关闭 extended thinking，响应快、成本低。复杂任务（&ldquo;重构状态机&rdquo;）开 adaptive thinking，让模型充分推理后再行动。</p>
<p>这是复杂度评估的第二个消费者——第一个是语义握手（决定要不要确认），第二个是推理深度（决定想多深）。</p>
<h3 id="硬性防护">硬性防护</h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<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;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<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;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#a6e22e">maxTurns</span>: <span style="color:#66d9ef">30</span>,      <span style="color:#75715e">// 单次事件最多 30 轮对话
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">maxBudgetUsd</span>: <span style="color:#66d9ef">5.0</span>, <span style="color:#75715e">// 单次事件最多花 $5
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>之前靠环路检测 hint（prompt 引导 agent 关闭 task），agent 可能不遵守。现在是 SDK 级别的硬限制——到了就停。这是&quot;纵深防御&quot;的又一层：prompt 引导是软限制，SDK 参数是硬限制。</p>
<h3 id="posttooluse-hook-替代流观察">PostToolUse Hook 替代流观察</h3>
<p>早期版本通过观察 SDK 消息流中的 <code>tool_use</code> 块来记录 agent 行为——但只能看到&quot;调了什么工具&rdquo;，看不到&quot;结果是什么&quot;。</p>
<p>升级到 PostToolUse hook 后：</p>
<table>
  <thead>
      <tr>
          <th>维度</th>
          <th>之前（流观察）</th>
          <th>现在（PostToolUse hook）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>能看到什么</td>
          <td>tool name + input</td>
          <td>tool name + input + result（含 exit code）</td>
      </tr>
      <tr>
          <td>标注精度</td>
          <td>&ldquo;编译验证&rdquo;（不知成败）</td>
          <td>&ldquo;编译通过(exit 0)&rdquo; 或 &ldquo;命令失败(exit 1)&rdquo;</td>
      </tr>
      <tr>
          <td>实现位置</td>
          <td>runtime 消息流循环</td>
          <td>SDK options.hooks</td>
      </tr>
  </tbody>
</table>
<p>这是一个典型的&quot;用平台能力替代自建逻辑&quot;的改进——SDK 原生支持的事情不需要自己 hack。</p>
<hr>
<p><em>本文记录的机制已在 Agent Mesh 中部署运行。代码位于 <code>meshd/src/tools/mesh-tools.ts</code>（复杂度评估 + 行为标注 + 独立验证）和 <code>meshd/src/agent/runtime.ts</code>（语义握手 + 验证清单 + SDK options 配置）。</em></p>
]]></content:encoded>
    </item>
  </channel>
</rss>
