<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: weiwuji</title>
    <description>The latest articles on DEV Community by weiwuji (@weiwuji).</description>
    <link>https://dev.to/weiwuji</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4057338%2Fdd2b9ebd-a384-45cf-ad65-8a96f200d9fd.png</url>
      <title>DEV Community: weiwuji</title>
      <link>https://dev.to/weiwuji</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/weiwuji"/>
    <language>en</language>
    <item>
      <title>From Loop to Graph: Our 52-Day Agent Engineering Evolution</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Wed, 19 Aug 2026 13:18:16 +0000</pubDate>
      <link>https://dev.to/weiwuji/from-loop-to-graph-our-52-day-agent-engineering-evolution-1naf</link>
      <guid>https://dev.to/weiwuji/from-loop-to-graph-our-52-day-agent-engineering-evolution-1naf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Pain&lt;/strong&gt;: You just wrapped your head around Loop Engineering, and now the AI world is talking about Graph Engineering. You learn one concept, the next arrives — forever chasing, never landing.&lt;br&gt;
&lt;strong&gt;What You'll Learn&lt;/strong&gt;: A real, working Agent engineering evolution path (Prompt → Context → Loop → Graph), each layer with physical evidence — not invented concepts, but steps I actually took over 52 days.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  0. Not a Concept Race, an Engineering Evolution
&lt;/h2&gt;

&lt;p&gt;A recent essay, "Beyond Workflow: Toward Graph Engineering," nailed the key point:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Many people think the upgrade path for Workflow is adding more nodes, more branches, and more conditionals. But once complexity truly grows, the question is no longer 'how to add nodes' — it's &lt;strong&gt;how to describe entities, relationships, state, and dynamic decisions in a changing environment&lt;/strong&gt;. That is the fundamental divide between Graph Engineering and traditional Workflow."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many treat Graph Engineering as "yet another concept" to chase. For practitioners like us, it is not a concept — it is the next stop on an evolution path. And I have genuinely walked that path.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Scaffold Evolution Overview: Prompt → Context → Loop → Graph
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F54gxwgpg62twhqjyitk0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F54gxwgpg62twhqjyitk0.png" alt="Agent scaffold evolution in four stages" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Core Question&lt;/th&gt;
&lt;th&gt;Abstraction Level&lt;/th&gt;
&lt;th&gt;Bottleneck&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;① Prompt Engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;How to make the model understand&lt;/td&gt;
&lt;td&gt;Single conversation&lt;/td&gt;
&lt;td&gt;Complex tasks can't finish in one shot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;② Context Engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;How to give enough context&lt;/td&gt;
&lt;td&gt;Single session&lt;/td&gt;
&lt;td&gt;Limited window / noisy input&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;③ Loop Engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;How to execute in loops&lt;/td&gt;
&lt;td&gt;Looping execution&lt;/td&gt;
&lt;td&gt;Runaway loops / no state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;④ Graph Engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;How to coordinate multiple agents&lt;/td&gt;
&lt;td&gt;Multi-agent orchestration&lt;/td&gt;
&lt;td&gt;State management / failure localization&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Evolution logic&lt;/strong&gt;: each stage solves the bottleneck of the previous one —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prompt (single-shot capability) → Context (memory capability) → Loop (execution capability) → Graph (organization capability)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. Our Context: Query the Index First, Then Feed Context
&lt;/h2&gt;

&lt;p&gt;My first stop was Context Engineering. The classic pitfall: &lt;strong&gt;feeding the entire knowledge base to the LLM&lt;/strong&gt; — context explosion, burning tokens, slow answers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj4689sq68oqhdqh3njv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj4689sq68oqhdqh3njv6.png" alt="Context engineering two-step method" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I switched to a two-step method:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Query the index&lt;/strong&gt;: the knowledge base maintains a static "concept → article" mapping table plus rule matching, locating "which nodes to look at" in milliseconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feed relevant fragments&lt;/strong&gt;: only the matched nodes go to the LLM — slimmer context, dramatically lower token cost&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is a lightweight RAG: no vector database, no embeddings — cheaper and faster for small knowledge bases.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Our Loop: Harness Engineering (the Core of 52 Days)
&lt;/h2&gt;

&lt;p&gt;The second stop was Loop Engineering — my deepest investment and biggest payoff. Its core isn't "let the loop run," it's &lt;strong&gt;making every loop iteration stronger&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4wtz40b1rkxjk4d378iw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4wtz40b1rkxjk4d378iw.png" alt="Harness engineering: error-immunity closed loop" width="800" height="415"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error occurs
→ ① error-ledger records it (symptom → root cause → fix → status)
→ ② correction sedimentation (distill into rules/skills)
→ ③ physical rule materialization (write into verify scripts/gates)
→ ④ gate immunity (blocked at the gate)
→ back to ① (new errors keep coming)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Real evidence&lt;/strong&gt; (what I ran over 52 days):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;error-ledger&lt;/strong&gt;: every corrected error is structurally recorded (symptom → root cause → fix → status)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daily self-evolution cron&lt;/strong&gt; (21:00 every night): automatic error review + hot-topic research + topic suggestions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gate matrix&lt;/strong&gt;: 6 physical gates before task output (task context exists / skill exists / rules executed / timeout / regression / schema)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maker/Checker separation&lt;/strong&gt;: producer and verifier are physically separate — no self-review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the complete closed loop from &lt;em&gt;"Self-Improving Agents Are Not a Myth"&lt;/em&gt; — &lt;strong&gt;reflection is probabilistic, evolution is physical&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Our Quasi-Graph: Multi-Agent Collaboration (in Progress)
&lt;/h2&gt;

&lt;p&gt;The third stop is Graph — &lt;strong&gt;we're already running it, we just hadn't named it in "graph" language yet&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F43ajppsytv0mpy26xyde.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F43ajppsytv0mpy26xyde.png" alt="Our multi-agent collaboration graph" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using my production business agent system as an example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nodes&lt;/strong&gt;: Email Agent / Report Agent / Ticketing Agent / Writing Agent (each with its own role)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edges&lt;/strong&gt;: Maker produces → Checker validates → gate allows/blocks (the collaboration relationship)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared state&lt;/strong&gt;: SQLite (ticketing) + ledgers + knowledge base (append-only)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Governance&lt;/strong&gt;: rules → verify scripts → gate matrix (the governance layer of the graph)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key insight&lt;/strong&gt;: we never wrote a line of "graph framework" code, yet our system is naturally a graph — &lt;strong&gt;because as complex tasks multiply, agents naturally evolve from "one person doing everything" to "a team working together"&lt;/strong&gt;. Graph isn't invented; it's the natural result of evolution.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. The Four-Layer Agent Engineering Scaffold (Practitioner Path)
&lt;/h2&gt;

&lt;p&gt;If you want to build your own Agent engineering system, build it in this order (the order I actually hit):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;What It Is&lt;/th&gt;
&lt;th&gt;Verification Standard&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;① Context Engineering&lt;/strong&gt; (foundation)&lt;/td&gt;
&lt;td&gt;Knowledge base + index + memory management&lt;/td&gt;
&lt;td&gt;Knowledge retrieval hit rate &amp;gt; 90%?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;② Loop Engineering&lt;/strong&gt; (skeleton)&lt;/td&gt;
&lt;td&gt;Loops + error records + correction sedimentation + gates&lt;/td&gt;
&lt;td&gt;The same error never happens twice?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;③ Observability&lt;/strong&gt; (nervous system)&lt;/td&gt;
&lt;td&gt;Gates + audit + tracing + ledgers&lt;/td&gt;
&lt;td&gt;Can you localize a failure within 5 minutes?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;④ Graph Engineering&lt;/strong&gt; (organization)&lt;/td&gt;
&lt;td&gt;Multi-agent + state management + dynamic decisions&lt;/td&gt;
&lt;td&gt;Adding an agent doesn't disturb the others?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Don't skip layers&lt;/strong&gt;: jumping straight to Graph without solid Context = a graph full of "amnesiac nodes." My 52-day order was Context → Loop → quasi-Graph, with evidence at every layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Cognitive Upgrade: Graph Is the Watershed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Graph Engineering is the watershed from "engineering" to "architecture."&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before (Prompt/Context/Loop): how to make an Agent do work (engineering)
After (Graph/platform): how to design an Agent organization (architecture)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Future AI competition isn't only about model capability — it's about &lt;strong&gt;how to design an intelligent system that reliably completes complex tasks&lt;/strong&gt;. That consensus is growing. And for designing "intelligent systems," the graph is the correct abstraction.&lt;/p&gt;

&lt;p&gt;For us: &lt;strong&gt;Graph Engineering is not another concept — it's the engineering answer to "how to manage agents once you have many."&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Where You Are Now
&lt;/h2&gt;

&lt;p&gt;You no longer settle for "learning one more concept" — you start asking "which layer is my agent system on now, and how should it evolve next."&lt;/p&gt;

&lt;p&gt;You are becoming the practitioner who &lt;strong&gt;turns concepts into scaffolds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Remember: &lt;strong&gt;Prompt asks, Context remembers, Loop runs, Graph organizes. Evolution with physical evidence at every layer is what real engineering looks like.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📖 Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Self-Improving Agents Are Not a Myth: A Complete Loop from Error-Ledger to Loop Engineering&lt;/em&gt; — the full practice of the Loop stage&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Practice = Technology × Scenario × Value: What Cognitive Monetization Means in the AI Era&lt;/em&gt; — the practitioner methodology&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Why "All-Powerful" Agents Fail: Scene Routing That Splits One Agent into 6 Experts&lt;/em&gt; — node splitting for multi-agent collaboration&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;The Observability Trio: Gate + Audit + Correction — A Feedback Loop for Commercial Agents&lt;/em&gt; — the governance layer of the graph&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;About the author: Wu Ji (无记) — AI &amp;amp; digitalization practitioner focused on Agent engineering, Loop Engineering, and digital transformation. Practical, hands-on tutorials — follow along and it just works.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>engineering</category>
      <category>graph</category>
    </item>
    <item>
      <title>Self-Improving Agents Are Not a Myth: A Complete Loop from Error-Ledger to Loop Engineering</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Mon, 17 Aug 2026 15:07:23 +0000</pubDate>
      <link>https://dev.to/weiwuji/self-improving-agents-are-not-a-myth-a-complete-loop-from-error-ledger-to-loop-engineering-3mlh</link>
      <guid>https://dev.to/weiwuji/self-improving-agents-are-not-a-myth-a-complete-loop-from-error-ledger-to-loop-engineering-3mlh</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Pain&lt;/strong&gt;: The mistake your agent made yesterday, it makes again today. You re-teach it every time — "Remember! Don't do that again!" — and it still forgets. A lot of people say "Self-Improving Agents are a myth," because for most agents, "reflection" is just talk. It never becomes system behavior.&lt;br&gt;
&lt;strong&gt;What You'll Learn&lt;/strong&gt;: A complete, production-proven self-improvement loop for agents (error-ledger → corrective distillation → rule materialization → gate immunity), so that every mistake the agent makes is a lesson the system permanently remembers.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  0. The Hottest Direction of 2026 — and the Most Questioned
&lt;/h2&gt;

&lt;p&gt;"Self-Improving Agents" is becoming a top-tier topic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stanford&lt;/strong&gt; launched a course (CS329A) devoted entirely to Self-Improving AI Agents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ICLR 2026&lt;/strong&gt; has a dedicated workshop on Recursive Self-Improvement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google engineer&lt;/strong&gt; Addy Osmani wrote &lt;em&gt;Self-Improving Coding Agents&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But on the other side of the debate, the loudest argument in the community is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Self-improving AI agent is a myth"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why a myth? Because for most agents, "self-improvement" looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reflect (the LLM says "I was wrong") → done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No record, no distillation, no verification — the same mistake happens next time. That isn't self-evolution. That's self-comfort.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Essence of Self-Improving: It's Not "Thinking", It's "Doing"
&lt;/h2&gt;

&lt;p&gt;What's the difference between a self-improving agent and an agent that simply "reflects"?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reflective: the LLM outputs a paragraph of "I'll be careful next time"
Self-improving: mistake → record → distill a rule → block it physically (impossible to repeat)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Reflection is probabilistic&lt;/strong&gt; (the LLM talks a good game, but may forget next time); &lt;strong&gt;evolution is physical&lt;/strong&gt; (the rule is written into the system, so next time it is guaranteed to be blocked).&lt;/p&gt;

&lt;p&gt;That's exactly why people call self-improvement a myth — most people are doing "reflection," not "evolution."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3fg3lxc7gw8u7ar7w07d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3fg3lxc7gw8u7ar7w07d.png" alt="Reflection vs Evolution" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. error-ledger: The Bookkeeping of Self-Evolution
&lt;/h2&gt;

&lt;p&gt;The first step of the self-improvement loop I run in production is the &lt;strong&gt;error-ledger&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Any mistake / failure / correction
  → logged into error-ledger.md (symptom → root cause → fix → status)
  → not just "noted down", but structured recording
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Symptom&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The new-email report shows only a count, no details&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Root cause&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Generated mechanically, no per-email analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fix&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Every email must show sender + subject + linked ticket ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;embedded (hardened into rules)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Why does structured recording matter?&lt;/strong&gt; Because an LLM's "memory" is unreliable — context gets compressed and overwritten. But &lt;strong&gt;files are physical&lt;/strong&gt;. They're always there.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Corrective Distillation: From "Record" to "Knowledge"
&lt;/h2&gt;

&lt;p&gt;Recording is only the first step. The second step is distilling mistakes into &lt;strong&gt;reusable rules&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Errors in the error-ledger
  → scanned daily / weekly
  → extract "the principle behind this error"
  → distill into: skills / SOPs / gates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What I actually do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every time I get corrected → log it into the error-ledger → &lt;strong&gt;extract the knowledge&lt;/strong&gt; → write it into a skill (SKILL.md) or a rule&lt;/li&gt;
&lt;li&gt;Example: my boss corrected me on "don't dismiss other people's viewpoints" → written into the skill as a "writing perspective iron rule" → every article written since then complies automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This step turns a "one-time mistake" into a "permanent asset."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3d309jcgym038bguyroa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3d309jcgym038bguyroa.png" alt="Corrective distillation" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Rule Materialization: Making the System "Impossible" to Repeat
&lt;/h2&gt;

&lt;p&gt;The highest form of knowledge isn't the kind written in a document — it's the kind &lt;strong&gt;baked into the physical logic of the system&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rule (a human remembers) → Script (the system executes) → Gate (forced interception)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My three levels of materialization:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Write into skills / docs&lt;/strong&gt;: followed automatically when the LLM loads them (probabilistic)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write into verify scripts&lt;/strong&gt;: validated automatically at check time (deterministic)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write into gates&lt;/strong&gt;: output is blocked outright if the gate fails (forced)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example: before an article goes out, &lt;code&gt;check_cross_links.py&lt;/code&gt; validates the cross-links → it fails the build if they're missing → publishing with defects becomes impossible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is the watershed between "evolution" and "reflection"&lt;/strong&gt; — reflection says "I'll try," evolution says "I guarantee."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv1o7u35gcz73b7j0vq3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv1o7u35gcz73b7j0vq3w.png" alt="Three levels of materialization" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. The Complete Loop: Self-Evolution as Loop Engineering
&lt;/h2&gt;

&lt;p&gt;String the four steps together and you get the full self-improvement loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A mistake happens
  → ① error-ledger records it (symptom → root cause → fix)
  → ② corrective distillation (distill the principle / rule)
  → ③ rule materialization (scripts / gates)
  → ④ gate immunity (impossible to repeat)
  → back to ① (new mistakes keep flowing in)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Every time the loop turns, the system learns one more lesson.&lt;/strong&gt; This isn't a myth — it's something I run every day in production.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj77vtcnstxhpht2xvw7e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj77vtcnstxhpht2xvw7e.png" alt="Self-improvement loop" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's the relationship between this loop and Loop Engineering? &lt;strong&gt;Loop Engineering turns an agent's thinking into an observable, controllable loop; self-evolution is what makes that loop stronger with every revolution.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Where You Are Now
&lt;/h2&gt;

&lt;p&gt;Right now, you're no longer satisfied with "just letting the agent reflect" — you're starting to think about "&lt;strong&gt;how to make the system physically remember its lessons&lt;/strong&gt;."&lt;/p&gt;

&lt;p&gt;You're becoming the kind of engineer who — &lt;strong&gt;turns every mistake into system immunity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Remember: &lt;strong&gt;reflection is probability, evolution is physics. Self-Improving Agents are not a myth — they just need the complete loop from error-ledger to Loop Engineering.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;🏷️ Entities: Self-Improving Agents, Loop Engineering, error-ledger, Gates&lt;br&gt;
💼 Value: Error immunity, System evolution, Rule materialization, Production-proven&lt;br&gt;
🧠 Cognition: Reflection is probability, evolution is physics — the complete loop from error-ledger to gate immunity&lt;/p&gt;




&lt;p&gt;📌 About the author&lt;/p&gt;

&lt;p&gt;&lt;em&gt;About the author: Wu Ji (无记) — AI / Agent / digital transformation practitioner. I only write about things I've actually built and run — no concepts without practice. Follow along, and let's turn cognition into income.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📖 Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.cnblogs.com/weiwuji/p/22473635.html" rel="noopener noreferrer"&gt;Choice Can't Stop at Tools — Two Ways the Content Flywheel Turns&lt;/a&gt; · How the flywheel cuts through the value layer&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cnblogs.com/weiwuji/p/22473634.html" rel="noopener noreferrer"&gt;Practice = Technology × Scenario × Value&lt;/a&gt; · The complete loop of turning cognition into income&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cnblogs.com/weiwuji/p/22456195.html" rel="noopener noreferrer"&gt;DeepSeek Open-Sourced Harness: Everything Is a Plugin, but the Real Gap Is Local&lt;/a&gt; · Foundations converge; the gap is in the details&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>数智化转型实战·第三篇：从SOP到组织免疫力——让事故变成能力</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Sun, 16 Aug 2026 13:14:47 +0000</pubDate>
      <link>https://dev.to/weiwuji/from-sop-to-immunity-the-4-step-loop-that-turns-every-incident-into-organizational-capability-3m5h</link>
      <guid>https://dev.to/weiwuji/from-sop-to-immunity-the-4-step-loop-that-turns-every-incident-into-organizational-capability-3m5h</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Pain&lt;/strong&gt;: The landing trio (onboarding checklist, checkpoint gates, rollback) lets a new hire take over your system in a week. Then you find a harsher truth: incidents still come, and they love hitting the exact same spot. My real record: Aug 3, three finished articles never entered the publish queue, patched that night; Aug 5, the same gap again - the English versions were translated but publishing and registration were skipped, patched again; Aug 6, the third time - all five Series D articles were live, and the queue still did not list them. The same "finished article not registered" pit, stepped into three times in five days.&lt;br&gt;
&lt;strong&gt;What You'll Learn&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why "knows how to fix" is not "has immunity" - fixing solves this one, immunity solves the next one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The 4-step organizational immunity loop&lt;/strong&gt;: incident → log → fix → feed rules back&lt;/li&gt;
&lt;li&gt;How each step maps to a real artifact: error-ledger entries, re-runnable verification, rules sunk into skills/scripts/gates&lt;/li&gt;
&lt;li&gt;How to verify immunity is actually working - two signals you can check with one command&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Opening: the same pit, we stepped into it three times
&lt;/h2&gt;

&lt;p&gt;In the previous article - &lt;em&gt;From Documents to Mechanisms: Onboarding Checklist, Checkpoint Gates, and Rollback&lt;/em&gt; - the trio got a new hire productive in one week. Then you discover a harsher fact: &lt;strong&gt;incidents still come, and they love hitting the exact same spot.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My real record: on Aug 3, during multi-platform publishing, we found that articles 17/19/20 had never entered the publish queue even though they were finished - patched that night. On Aug 5, the same gap again: the English versions were translated, but publishing and registration were not done - patched again. On Aug 6, the third time: all five Series D articles were already live, and the queue still had no trace of them. The same "finished article not registered" pit, five days, three times.&lt;/p&gt;

&lt;p&gt;The team is not lazy; the system has no immunity. &lt;strong&gt;One person stepping into a pit is a lesson; an organization stepping into the same pit repeatedly is amnesia.&lt;/strong&gt; Today's cure is a four-step loop: &lt;strong&gt;incident → log → fix → feed rules back&lt;/strong&gt;. This loop is not a concept; it is a component running in my own system right now, and every command can be reproduced on your machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why "knows how to fix" is not "has immunity"
&lt;/h2&gt;

&lt;p&gt;Most teams' "review" looks like this: incident happens → the person in charge fixes it overnight → a message goes into the group chat: "fixed, be careful next time" → three months later the same pit explodes again. Why? Because &lt;strong&gt;fixing solves "this time"; immunity solves "next time".&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gap&lt;/th&gt;
&lt;th&gt;What it looks like&lt;/th&gt;
&lt;th&gt;Consequence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No logging&lt;/td&gt;
&lt;td&gt;Fixed and done, no record&lt;/td&gt;
&lt;td&gt;The same troubleshooting starts from zero again&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No feedback&lt;/td&gt;
&lt;td&gt;The record lies in a document&lt;/td&gt;
&lt;td&gt;The rule never reaches the execution layer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No interception&lt;/td&gt;
&lt;td&gt;The rule depends on people remembering it&lt;/td&gt;
&lt;td&gt;Newcomers do not know the old pits&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The essential difference: fixing puts the system "back to normal"; immunity makes the system "unlikely to break in the future". To achieve the latter, every incident must become an increment of the rules - this is what Loop Engineering looks like at the organizational level.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbvuzrqv3gx0obvkrkmls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbvuzrqv3gx0obvkrkmls.png" alt="Individual debugging vs organizational immunity: left side three red cards showing the same pit stepped into three times, right side three teal cards showing the pit no longer recurs after logging and rule feedback; bottom line: individuals debug by memory, organizations immunize by mechanism" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Log the incident - turn "pits you stepped into" into "organizational assets"
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem: incident memory lives in individual heads.&lt;/strong&gt; The person involved remembers it clearly, but the organization has no memory. The person leaves, the lesson leaves with them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution: create an error ledger and log in four parts.&lt;/strong&gt; First, create the error knowledge base file &lt;code&gt;/root/shared/error-ledger.md&lt;/code&gt;; second, every incident gets one entry with a fixed four-part structure: symptom → root cause → fix → status. Our knowledge base has accumulated more than 30 real incidents. Here is a real entry (the 2026-08-01 Hashnode duplicate-publish incident):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## 2026-08-01 · Hashnode duplicate publish incident&lt;/span&gt;
&lt;span class="gs"&gt;**Symptom:**&lt;/span&gt; A1/A2/A3/A4/A5/A8 each appeared twice on Hashnode
&lt;span class="gs"&gt;**Root cause:**&lt;/span&gt; the "Draft not found" error actually meant the publish had
        succeeded; the retry logic caused duplicates
&lt;span class="gs"&gt;**Fix:**&lt;/span&gt; dedupe before publishing - skip when the title already exists;
        when "Draft not found", first check whether the article is published
&lt;span class="gs"&gt;**Status:**&lt;/span&gt; dedupe logic added to multi_publish.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The four-part structure is not a format; it forces you to think clearly: symptom states "what you saw", root cause digs to the mechanism layer, fix goes down to command level, and status states clearly whether the loop is closed. &lt;strong&gt;A pit that is not closed is written in the open, not hidden in your head.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Verification&lt;/strong&gt;: whenever you hit a new error, the first step is not to fix it - it is to open the error ledger and search history. Run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"duplicate&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;429&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;Broken pipe"&lt;/span&gt; /root/shared/error-ledger.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;10 seconds to a historical answer, no need to troubleshoot from zero.&lt;/p&gt;

&lt;p&gt;🩸 &lt;strong&gt;Pitfall&lt;/strong&gt;: on Aug 2, the daily report trend date showed question marks; after troubleshooting we found the &lt;code&gt;collected_at&lt;/code&gt; field was missing - but this pit had never been logged, so the lesson was wasted. The rule now: &lt;strong&gt;log today's incident today, do not wait for the review meeting.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;▸ &lt;strong&gt;Cognitive shift&lt;/strong&gt;: logging is essentially &lt;strong&gt;turning "pits you stepped into" from individual memory into organizational assets&lt;/strong&gt; - assets appreciate, memories depreciate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyni1so4wz9iz6qngcryp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyni1so4wz9iz6qngcryp.png" alt="The error ledger four-part entry structure: four vertical cards in order - symptom red, root cause purple, fix blue, status teal - each card with a real field example; bottom line: the four-part structure is not a format, it forces you to think the incident through" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Verify the fix - "fixed" is not the end, gate passed is
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem: announcing "fixed" right after fixing is the fastest path to recurrence.&lt;/strong&gt; Whether a fix actually worked cannot rely on feeling; it relies on evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution: every fix must come with verification, and the verification must be re-runnable.&lt;/strong&gt; When we handled the "gate_en_articles.py Chinese detection false positive" incident, the fix was changing the detection logic (character count → line count), and the verification was running three regression cases (compliant article passes / Chinese residue blocked / passes after the fix):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# After the fix, run the verification; 4/4 PASS is the real closure&lt;/span&gt;
python3 /root/hermes-harness/scripts/validate_article.py check article-25.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real output (I ran it on my machine):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;check: article-25.md | PASS
body: 3666 chars
quality score: 100/100 (16/16 checks passed)
ALL CHECKS PASSED - article meets the publish standard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🩸 &lt;strong&gt;Pitfall&lt;/strong&gt;: on Aug 5, fixing the Dev.to tag error (the tag contained a hyphen &lt;code&gt;ab-testing&lt;/code&gt;, and the platform only allows alphanumeric characters - fixed to &lt;code&gt;abtesting&lt;/code&gt;). Right after fixing, we re-ran the publish and confirmed the 422 was gone, and only then changed the status in the error ledger to "fixed". &lt;strong&gt;Verification is not optional; it is the switch that closes the loop.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;▸ &lt;strong&gt;Cognitive shift&lt;/strong&gt;: verification is essentially &lt;strong&gt;turning "I fixed it" from a self-report into a set of re-runnable evidence&lt;/strong&gt; - evidence speaks, self-reports lie.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Feed the rules back - stop the next incident before it happens
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem: logged, fixed - and the rule still lies in the document.&lt;/strong&gt; The next incident happens anyway. The key step of an immune system is to sink rules from the "knowledge layer" down to the "execution layer" - into skills, into scripts, into gates.&lt;/p&gt;

&lt;p&gt;Our real feedback actions, three paths:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Sink into the skill&lt;/strong&gt;: on Jul 31, the WeChat push returned 501 (consecutive SQL keywords in the body triggered security risk control); the fix was to express such patterns as pseudocode/field descriptions, &lt;strong&gt;fed back into the content-repurpose skill&lt;/strong&gt;, so future articles avoid it automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Sink into the script&lt;/strong&gt;: on Aug 1, the Dev.to 429 rate limit (about 5 posts per 30-second window); the fix was publish interval &amp;gt;= 30 seconds and &amp;lt;= 3 posts per batch, &lt;strong&gt;fed back into multi_publish.py&lt;/strong&gt; with an automatic sleep; the same day's Hashnode duplicate-publish incident got its dedupe logic written directly into the publish script.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Sink into the config&lt;/strong&gt;: on Aug 1, we found the legacy publish CLI was broken (only accepts JSON, depends on a local service, cover URL upload returns 40113); the fix was switching the publish path; on Aug 8, the old command and plaintext credentials were removed from the cron task together, &lt;strong&gt;fed back into the task config&lt;/strong&gt;, never misused again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Real effect after feedback: the publish script auto-dedupes and auto-rate-limits&lt;/span&gt;
&lt;span class="c"&gt;# same title already exists -&amp;gt; skip; between publishes -&amp;gt; auto sleep 30s&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"dedupe&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;sleep&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;30"&lt;/span&gt; /root/tools/baoyu-post-to-wechat/scripts/wechat-api.ts | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🩸 &lt;strong&gt;Pitfall&lt;/strong&gt;: feedback is the easiest step to skip. In the Aug 3 queue gap, the fix was "re-publish", but the feedback action (registering the queue right after writing) was not done at the time - so Aug 5 and Aug 6 it happened again, back to back. &lt;strong&gt;A fix without feedback is burying the pit again.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;▸ &lt;strong&gt;Cognitive shift&lt;/strong&gt;: feedback is essentially &lt;strong&gt;turning "be careful next time" from a verbal reminder into a line of checking code&lt;/strong&gt; - once the rule enters the execution layer, it does not depend on anyone remembering it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9qhcbtjetnzzx7ab41mc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9qhcbtjetnzzx7ab41mc.png" alt="Rule feedback path: left red error knowledge base card, middle purple skill consolidation card, right teal gate interception card; bottom blue card shows the same error is blocked directly the second time; bottom line: the end of error feedback is stopping the next incident before it happens" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Verify immunity - the same pit does not recur, and if it recurs you can look it up in seconds
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem: after the feedback, how do you know immunity actually works?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution: two signals.&lt;/strong&gt; First, the same error no longer recurs the same way; second, even if it recurs, you can find the historical answer within 10 seconds.&lt;/p&gt;

&lt;p&gt;Our cron task crashed three days in a row (Aug 4/7/8, dying at startup). The first diagnosis was "one-night infrastructure failure"; after the Aug 7 recurrence it was corrected to "recurrent occasional failure"; after the third time on Aug 8 it was upgraded to "persistent occasional failure" and physical governance began (removing the broken command, updating the task config). &lt;strong&gt;This diagnosis-correction chain itself is the immune system at work&lt;/strong&gt; - every recurrence makes the understanding more accurate.&lt;/p&gt;

&lt;p&gt;Another real case: after the queue gap recurred three times (Aug 3/5/6), we hardened "register the queue immediately when writing is done" into the process, and that class of gap has not appeared since.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Verification&lt;/strong&gt;: one command tells you whether immunity is working:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"fixed"&lt;/span&gt; /root/shared/error-ledger.md    &lt;span class="c"&gt;# fixed entries keep growing&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"queue gap"&lt;/span&gt; /root/shared/error-ledger.md &lt;span class="c"&gt;# when did it last recur&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;▸ &lt;strong&gt;Cognitive shift&lt;/strong&gt;: verifying immunity is essentially &lt;strong&gt;turning "we will not do it again" from an optimistic expectation into checkable history&lt;/strong&gt; - the thickness of the error ledger is the scale of organizational immunity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpyk4n8duot11hfqevmyz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpyk4n8duot11hfqevmyz.png" alt="The four-step immunity loop: four nodes in a closed loop - incident happens red, log purple, fix blue, feed rules back teal; arrows labeled log, fix, feedback, immunity; bottom line: an incident is not shame, it is data - the thicker the error ledger, the more stable the organization" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Before vs After: the same incident, two endings
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Before: individual debugging&lt;/th&gt;
&lt;th&gt;After: organizational immunity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Incident record&lt;/td&gt;
&lt;td&gt;Fixed and forgotten, "fixed" in the group chat&lt;/td&gt;
&lt;td&gt;Logged in four parts the same day, everyone can look it up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Troubleshooting cost&lt;/td&gt;
&lt;td&gt;The same error investigated from scratch&lt;/td&gt;
&lt;td&gt;grep gives the historical answer in 10 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Where the rule lives&lt;/td&gt;
&lt;td&gt;In the lead's head&lt;/td&gt;
&lt;td&gt;In skills / scripts / gates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recurrence rate&lt;/td&gt;
&lt;td&gt;The same class of pit stepped into repeatedly&lt;/td&gt;
&lt;td&gt;Rules intercept, the same pit does not recur&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Newcomer onboarding&lt;/td&gt;
&lt;td&gt;Step into every pit from scratch&lt;/td&gt;
&lt;td&gt;The error ledger is a pit-avoidance map&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Why an immune system beats a perfect system
&lt;/h2&gt;

&lt;p&gt;A lot of teams chase "never making mistakes". Wrong direction. &lt;strong&gt;Chasing never making mistakes only makes mistakes get hidden; chasing immunity makes mistakes become nutrition.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The immune system has three properties, and they map exactly to the three things we built: &lt;strong&gt;memory&lt;/strong&gt; - the error ledger makes every incident remembered; &lt;strong&gt;learning&lt;/strong&gt; - rule feedback makes every fix change system behavior; &lt;strong&gt;detection&lt;/strong&gt; - gates and verification make recurrence discoverable. Remove any one of the three and it is not immunity, it is just "fixing a bit faster".&lt;/p&gt;

&lt;p&gt;Go one layer deeper: the immune system solves the "survival problem" of organizational knowledge. When individuals debug, knowledge lives in human heads - the person leaves, the knowledge leaves. When organizations immunize, knowledge lives in mechanisms - as long as the mechanism is there, the knowledge is there. The third real question of digital transformation is not "make the system smarter"; it is &lt;strong&gt;letting the organization evolve from "knows how to fix" to "does not break"&lt;/strong&gt; - growing a memory every time it makes a mistake. This is the complete shape of Loop Engineering at the organizational level.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary: 3 things you can start today
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create an error ledger&lt;/strong&gt;: four parts (symptom/root cause/fix/status), log today's incident today&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every fix must come with verification&lt;/strong&gt;: after fixing, run a re-runnable verification command; only pass means change the status&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Force the feedback&lt;/strong&gt;: after every fix, sink the rule into a skill, a script, or a gate - pick one of the three&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do these three and your organization starts to have immunity. This is the third foundation stone of digital transformation - &lt;strong&gt;from "knows how to fix" to "does not break", from "individuals remember" to "mechanisms remember".&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next article: LLM-as-Judge: How to Calibrate Your Judge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After rules are fed back into the system, a new question appears: if the judge deciding "right or wrong" is itself an AI, who verifies that the judge is not blind? Next we enter the Agent evaluation and observability series, and talk about calibrating the AI judge - the last link of organizational immunity: even "judgment" itself must be examined.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧭 Cognitive Index
&lt;/h2&gt;

&lt;p&gt;🏷️ Entities: error-ledger · multi_publish.py · content-repurpose · four-part logging&lt;br&gt;
💼 Value: organizational immunity · incident closure · knowledge consolidation&lt;br&gt;
🧠 Cognition: from "knows how to fix" to "does not break" - the thickness of the error ledger is the scale of immunity&lt;/p&gt;

&lt;p&gt;&lt;em&gt;About the author: Wu Ji (无记) — AI / Agent / digital transformation practitioner. Only writes things that actually ran end to end, no concepts for their own sake. Follow along and it just works.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>engineering</category>
      <category>team</category>
    </item>
    <item>
      <title>In Diagrams, Precision &gt; Pretty: Why AI Technical Articles Use Code-Generated Images</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Fri, 14 Aug 2026 08:18:14 +0000</pubDate>
      <link>https://dev.to/weiwuji/in-diagrams-precision-pretty-why-technical-articles-use-code-generated-images-3nhc</link>
      <guid>https://dev.to/weiwuji/in-diagrams-precision-pretty-why-technical-articles-use-code-generated-images-3nhc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Pain&lt;/strong&gt;: When adding diagrams to technical articles, there are two classic pitfalls — either you paste dense screenshots that readers can't make out, or you have AI draw a lovely illustration that nobody can tell what it's about.&lt;br&gt;
&lt;strong&gt;What You'll Learn&lt;/strong&gt;: An understanding of the principle "precision &amp;gt; pretty" in diagrams, and why code-generated images are the best choice for technical articles — precise as the baseline, and good-looking on top of it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  0. The essence of diagrams: making the point clear
&lt;/h2&gt;

&lt;p&gt;Diagrams in technical articles aren't decoration — they're &lt;strong&gt;information carriers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A good technical diagram: one glance and the reader grasps "how this flow works," "where this comparison differs," "how many layers this architecture has."&lt;/p&gt;

&lt;p&gt;A bad technical diagram: beautiful, but the reader leaves more confused than before.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Two ways to make diagrams
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Way A: AI text-to-image (let the model draw)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input: a description → Output: an AI-generated image
Pros: great visual texture (3D materials/magazine feel)
Risks: ⚠️ Text can be wrong/blurry/cropped (AI-drawn text is uncontrollable)
      ⚠️ Data can be mangled (chart semantics redrawn)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Way B: Code-generated images (SVG rendering)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input: structured data → code generates SVG → renders to PNG
Pros: ✅ Text 100% precise (code-rendered)
     ✅ Data 100% precise (values fully controlled)
     ✅ Free + fully reproducible
Risks: ⚠️ Visual quality requires design work (template-driven)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9zfvadhtvvzusvo5qu14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9zfvadhtvvzusvo5qu14.png" alt="Comparing the two approaches"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Why "precision &amp;gt; pretty"
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What's special about technical articles
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;General article diagrams: pretty is enough (emotion/atmosphere)
Technical article diagrams: precision is the baseline (information/logic)

Wrong process label → readers follow it and get it wrong
Wrong data on a chart → readers believe it, and everything built on it is wrong
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;One wrong diagram in a technical article can destroy the trust of the entire piece.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  An example
&lt;/h3&gt;

&lt;p&gt;Say you're diagramming an "agent workflow":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text-to-image: the AI might render "User Input" as "System Input," the label blurs, and readers have to guess&lt;/li&gt;
&lt;li&gt;Code-generated: labels like "User Input," "AI Execution," "Result Check" are pixel-perfect&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fms7f7aqp7ky4c3d52h6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fms7f7aqp7ky4c3d52h6a.png" alt="Precision vs. blur"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. My approach: precision first, aesthetics second
&lt;/h2&gt;

&lt;p&gt;My diagram system: &lt;strong&gt;code-generated (SVG) as the backbone, borrowing the visual texture of AI imagery.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SVG code generation (guarantees precision)
  + material-style 3D look (borrows the pretty)
  + short labels (2-5 characters, only labels inside the image)
  + QA checks (labels legible / data correct / no cropping)
  = diagrams that are both precise and good-looking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Concretely:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Precision&lt;/strong&gt;: SVG code rendering — text/data 100% under control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aesthetics&lt;/strong&gt;: material-style visuals (soft shadows / IKB blue / Swiss layout) — learn the "texture" from AI text-to-image style, skip its "uncontrollability"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Short labels&lt;/strong&gt;: in-image text ≤ 6 characters — "Result Check," not "Check the Execution Result"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QA&lt;/strong&gt;: after generation, check labels / data / cropping&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbwo36p4ryq0n7zzosg7y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbwo36p4ryq0n7zzosg7y.png" alt="My diagram approach"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Why I don't use AI text-to-image for in-body diagrams
&lt;/h2&gt;

&lt;p&gt;To be clear: AI text-to-image &lt;strong&gt;isn't bad&lt;/strong&gt; — it's great for covers, banners, and decorative illustrations.&lt;/p&gt;

&lt;p&gt;My choice is &lt;strong&gt;division of labor by purpose&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;In-body concept/flow diagrams&lt;/td&gt;
&lt;td&gt;Code-generated (SVG)&lt;/td&gt;
&lt;td&gt;Text/data must be precise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Covers/Banners&lt;/td&gt;
&lt;td&gt;AI text-to-image&lt;/td&gt;
&lt;td&gt;Decorative, no text requirements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real screenshots/command output&lt;/td&gt;
&lt;td&gt;Actual captures&lt;/td&gt;
&lt;td&gt;The iron rule of authenticity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  5. Where you are now
&lt;/h2&gt;

&lt;p&gt;Right now, you've stopped paying for "a pretty image" — you've started paying for "an image that explains itself."&lt;/p&gt;

&lt;p&gt;You're becoming the kind of — &lt;strong&gt;strict reader who looks at a diagram and asks "does it explain the point?" before "does it look good?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Remember: &lt;strong&gt;precision &amp;gt; pretty. A technical article's diagrams are information carriers, not decorations — but on a precise foundation, they can absolutely be prettier.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;🏷️ Substance: SVG diagrams, code generation, AI text-to-image, short labels&lt;br&gt;
💼 Value: accurate information, trust-building, visual texture, diagram efficiency&lt;br&gt;
🧠 Cognition: Precision &amp;gt; pretty in diagrams — a diagram is an information carrier, not a decoration, but on a precise foundation it can be prettier&lt;/p&gt;




&lt;p&gt;📌 About the author&lt;br&gt;
&lt;em&gt;About the author: Wu Ji (无记) — AI / Agent / digital transformation practitioner. I only write about things I've actually built and run — no concepts without practice. Follow along, and let's turn cognition into income.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📖 Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/weiwuji/in-diagrams-precision-pretty-why-technical-articles-use-code-generated-images-3nhc"&gt;In Diagrams, Precision &amp;gt; Pretty&lt;/a&gt; · This article&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cnblogs.com/weiwuji/p/22258082.html" rel="noopener noreferrer"&gt;Automate Your Blog Images&lt;/a&gt; · Early practice of the diagram system&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cnblogs.com/weiwuji/p/22258080.html" rel="noopener noreferrer"&gt;The One-Person Editorial Department&lt;/a&gt; · The full content production system&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>The Choice Can't Stop at Tools: Agent Content Flywheel, Two Ways to Spin</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Fri, 14 Aug 2026 08:17:30 +0000</pubDate>
      <link>https://dev.to/weiwuji/the-choice-cant-stop-at-tools-two-ways-to-spin-a-content-flywheel-4890</link>
      <guid>https://dev.to/weiwuji/the-choice-cant-stop-at-tools-two-ways-to-spin-a-content-flywheel-4890</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Pain&lt;/strong&gt;: You've produced a lot of content and built up some influence, yet you keep feeling "the flywheel that's spinning is someone else's, not mine." Why? It may not be a content-quality problem — your flywheel may simply be stuck at the tool layer.&lt;br&gt;
&lt;strong&gt;What You'll Learn&lt;/strong&gt;: A clear view of the two ways to spin a content flywheel, and why "the choice can't stop at tools" — tools are means, systems are assets, value creation is the endgame.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  0. First, see clearly: what a flywheel is
&lt;/h2&gt;

&lt;p&gt;The flywheel effect: &lt;strong&gt;content brings influence, and influence brings more content&lt;/strong&gt; — each turn charges up the next.&lt;/p&gt;

&lt;p&gt;But here's the key question: &lt;strong&gt;what spins your flywheel?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Two ways to spin the flywheel
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Spin A: the tool-layer flywheel
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I build a useful tool
  → people use it (influence)
  → I become known
  → I sell more tools
  → more content material
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This flywheel's traits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The output is a &lt;strong&gt;tool&lt;/strong&gt; (Skill/code/templates)&lt;/li&gt;
&lt;li&gt;The content type is &lt;strong&gt;tool tutorials&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The moat is the &lt;strong&gt;tool ecosystem&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Spin B: the value-layer flywheel
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Practice (real business runs successfully)
  → Systematization (SOPs/methodologies/architectures, codified and replicable)
  → Influence (expert personal brand)
  → Business value creation (real application scenarios)
  → more practice material
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This flywheel's traits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The output is a &lt;strong&gt;system&lt;/strong&gt; (methodologies/architectures, not a single tool)&lt;/li&gt;
&lt;li&gt;The content type is &lt;strong&gt;hands-on practice + cognitive upgrade&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The moat is &lt;strong&gt;methodology + experience&lt;/strong&gt; (hard to copy)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr1n0s6u30zkj8ogw49sb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr1n0s6u30zkj8ogw49sb.png" alt="Comparing the two flywheels"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Why "the choice can't stop at tools"
&lt;/h2&gt;

&lt;p&gt;The tool-layer flywheel isn't wrong — it's real, it works, it's proven. &lt;strong&gt;But the choice can't stop at tools&lt;/strong&gt;, because:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Tools get replaced
&lt;/h3&gt;

&lt;p&gt;A tool that's great today may have a better one tomorrow. But &lt;strong&gt;methodologies don't go stale&lt;/strong&gt; — the ability to "systematize a complex system" stays valid no matter which tools you use.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. A tool is a single point; a system is a network
&lt;/h3&gt;

&lt;p&gt;One tool solves one problem; one system solves a class of problems. &lt;strong&gt;A system can be replicated into any scenario&lt;/strong&gt; — individuals can use it, teams can use it, organizations can use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Tools build "knowing how to use"; systems build "understanding"
&lt;/h3&gt;

&lt;p&gt;Reader after a tool tutorial: "oh, this tool can be used like that."&lt;br&gt;
Reader after a system methodology: "I understand the essence of this problem — I can design it myself now."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F86odk6t7ym1mz78bmq4b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F86odk6t7ym1mz78bmq4b.png" alt="Tools vs. systems"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  3. How to spin the value-layer flywheel (my practice)
&lt;/h2&gt;

&lt;p&gt;My approach: &lt;strong&gt;every piece of content gets distilled into part of a system.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One practice article
  → extract a reusable SOP/methodology
  → codify it into a system (architecture/process/checklist)
  → reuse it directly next time a similar problem comes up
  → the system becomes more complete with every turn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This isn't "making content" — it's "&lt;strong&gt;building a system with content&lt;/strong&gt;." Every article is one brick in the system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4crmh5sukyuq04mroo0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4crmh5sukyuq04mroo0w.png" alt="The system flywheel"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The two flywheels aren't opposites
&lt;/h2&gt;

&lt;p&gt;Let me be clear: &lt;strong&gt;I'm not saying the tool-layer flywheel is bad&lt;/strong&gt; — for many creators it's more than enough, and it's highly efficient.&lt;/p&gt;

&lt;p&gt;What I'm saying is: &lt;strong&gt;if your goal is long-term value creation, the choice can't stop at tools.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tool-layer flywheel: fast, but low ceiling (selling tools/subscriptions)
Value-layer flywheel: slow, but high ceiling (consulting/training/products/system licensing)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can spin the tool-layer flywheel first to build influence, then upgrade to the value-layer flywheel — &lt;strong&gt;from "I built something useful" to "I built a replicable system."&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Where you are now
&lt;/h2&gt;

&lt;p&gt;Right now, you're no longer satisfied with "making content" — you're starting to ask "&lt;strong&gt;what does this content ultimately settle into.&lt;/strong&gt;"&lt;/p&gt;

&lt;p&gt;You're becoming the kind of — &lt;strong&gt;long-termist who, before publishing anything, asks "can this become part of a system?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Remember: &lt;strong&gt;tools are means, systems are assets, value creation is the endgame. The choice can't stop at tools.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;🏷️ Substance: content flywheel, systematization, methodology, tool ecosystem&lt;br&gt;
💼 Value: value creation, replicable systems, long-term assets, influence&lt;br&gt;
🧠 Cognition: The choice can't stop at tools — tools are means, systems are assets, value creation is the endgame&lt;/p&gt;




&lt;p&gt;📌 About the author&lt;br&gt;
&lt;em&gt;About the author: Wu Ji (无记) — AI / Agent / digital transformation practitioner. I only write about things I've actually built and run — no concepts without practice. Follow along, and let's turn cognition into income.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📖 Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/weiwuji/the-choice-cant-stop-at-tools-two-ways-to-spin-a-content-flywheel-4890"&gt;The Choice Can't Stop at Tools&lt;/a&gt; · This article&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/weiwuji/practice-technology-x-scenario-x-value-what-cognitive-monetization-really-means-22ja"&gt;Practice = Technology × Scenario × Value&lt;/a&gt; · The complete loop of cognitive monetization&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cnblogs.com/weiwuji/p/22258103.html" rel="noopener noreferrer"&gt;Correction Sedimentation&lt;/a&gt; · The core mechanism of systematization&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>Practice = Technology x Scenario x Value: What Cognitive Monetization Means in the AI Era</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Fri, 14 Aug 2026 08:17:22 +0000</pubDate>
      <link>https://dev.to/weiwuji/practice-technology-x-scenario-x-value-what-cognitive-monetization-really-means-22ja</link>
      <guid>https://dev.to/weiwuji/practice-technology-x-scenario-x-value-what-cognitive-monetization-really-means-22ja</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Pain&lt;/strong&gt;: You've learned a lot of technology — AI, agents, large models — yet you keep feeling "I've learned so much, but I can't put it to use." Why? Because you've mistaken "practice" for "writing code." Real practice is technology meeting scenarios and creating value — a closed loop of all three.&lt;br&gt;
&lt;strong&gt;What You'll Learn&lt;/strong&gt;: The complete formula "practice = technology × scenario × value," and why this is the true path to monetizing cognition.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  0. First, let's align on a concept: what "practice" is NOT
&lt;/h2&gt;

&lt;p&gt;Many people think "practice" means getting your hands dirty — running a demo, training a model, standing up a system.&lt;/p&gt;

&lt;p&gt;That's "tinkering," not "practice."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tinkering (you did it)      → Technology layer: I got it running
Practice (you made it work) → Value layer: the technology created business value in a real scenario
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where's the difference? &lt;strong&gt;Tinkering means "I know how to use it"; practice means "I used it to solve a problem."&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Practice = Technology × Scenario × Value (all three are non-negotiable)
&lt;/h2&gt;

&lt;p&gt;Here's my definition of practice:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Technology must meet real scenarios and create genuine business and scenario value — only then can you monetize cognition.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Broken down, it's three indispensable elements:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn6x3i0bimw3wpm0lsdqu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn6x3i0bimw3wpm0lsdqu.png" alt="The closed loop of the three elements"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Element&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;th&gt;Without it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Technology&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI / Agents / digital-intelligence transformation (real substance, not concepts)&lt;/td&gt;
&lt;td&gt;No technology = empty talk about scenarios&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Real business scenarios / production environments / actual projects&lt;/td&gt;
&lt;td&gt;No scenario = repackaged popular science&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Business value + scenario value&lt;/td&gt;
&lt;td&gt;No value = wasted effort&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Why "×" and not "+"?&lt;/strong&gt; Because the three multiply — if any one of them is zero, the result is zero.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Technology(1) × Scenario(1) × Value(0) = 0  ← you got it running, but created no value
Technology(1) × Scenario(0) × Value(1) = 0  ← great idea, but never landed in a scenario
Technology(0) × Scenario(1) × Value(1) = 0  ← knows the business, but not the technology
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. Why "× Scenario" is the dividing line
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Scenario is the bridge between technology and value.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Take the same agent technology:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Without a scenario → run a demo, post a tech note, readers walk away thinking "oh, it runs"&lt;/li&gt;
&lt;li&gt;With a scenario → dropped into a real business process, solving a real problem, readers walk away thinking "I want to use it like this too"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Scenario turns a "technology demo" into a "business solution."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff1ycmirlzkcfloqofrvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff1ycmirlzkcfloqofrvv.png" alt="Scenario is the bridge"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From my own experience: the same agent-orchestration technique, explained on its own, is "yet another tutorial." Put it in a real business scenario — what it handles every day, how much manual work it saves, what pitfalls we hit — and it instantly becomes "a replicable methodology." &lt;strong&gt;That's the multiplier effect of scenario.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Why "× Value" is the finish line
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Value is the acceptance criterion of practice.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Getting a technology to run isn't the end. You have to ask: &lt;strong&gt;what value did this technology create, in what scenario?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How much time did it save?&lt;/li&gt;
&lt;li&gt;How much cost did it cut?&lt;/li&gt;
&lt;li&gt;How much efficiency did it gain?&lt;/li&gt;
&lt;li&gt;What problem did it solve that couldn't be solved before?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff3kuktfzx67ldhp1bdt4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff3kuktfzx67ldhp1bdt4.png" alt="Value acceptance check"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A problem without value isn't worth practicing; a practice without value isn't worth writing about.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Cognitive monetization: the inevitable result of the closed loop
&lt;/h2&gt;

&lt;p&gt;Once technology × scenario × value closes the loop, &lt;strong&gt;cognitive monetization becomes a natural outcome&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Technology (what you can do) → Scenario (where you apply it) → Value (what you create)
        ↓                          ↓
Cognitive upgrade (readers learn from your articles)    Practice landing (readers follow your playbook)
        ↓                          ↓
            Cognitive monetization (trust + paying users + influence)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why do readers trust you? Because you're not talking concepts — you're talking about &lt;strong&gt;real substance that has created value in real scenarios&lt;/strong&gt;. That's the moat of "practitioner cognitive upgrade" — &lt;strong&gt;competitors talk concepts; we deliver substance. Competitors talk technology; we talk scenario value.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Where you are now
&lt;/h2&gt;

&lt;p&gt;Right now, you're no longer satisfied by the thrill of "getting a demo to run."&lt;/p&gt;

&lt;p&gt;You're becoming the kind of — &lt;strong&gt;strict practitioner who, before learning any technology, asks "what value can it create in what scenario."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Remember: &lt;strong&gt;technology is the means, scenario is the bridge, value is the destination. Only when all three close the loop is it real cognitive monetization.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;🏷️ Substance: technology practice, scenario application, value creation, cognitive monetization&lt;br&gt;
💼 Value: business value, scenario value, practice methodology, cognitive upgrade&lt;br&gt;
🧠 Cognition: Practice = Technology × Scenario × Value — only when all three close the loop is it real cognitive monetization&lt;/p&gt;




&lt;p&gt;📌 About the author&lt;br&gt;
&lt;em&gt;About the author: Wu Ji (无记) — AI / Agent / digital transformation practitioner. I only write about things I've actually built and run — no concepts without practice. Follow along, and let's turn cognition into income.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📖 Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/weiwuji/practice-technology-x-scenario-x-value-what-cognitive-monetization-really-means-22ja"&gt;Practice = Technology × Scenario × Value&lt;/a&gt; · This article&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/weiwuji/the-choice-cant-stop-at-tools-two-ways-to-spin-a-content-flywheel-4890"&gt;The Choice Can't Stop at Tools&lt;/a&gt; · The flywheel that penetrates the value layer&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cnblogs.com/weiwuji/p/22240384.html" rel="noopener noreferrer"&gt;The 4-Layer Architecture of a One-Person OPC&lt;/a&gt; · The practical shape of this system&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>DeepSeek Open-Sourced Its Harness: Everything Is a Plugin, But the Real Gap Is in the Details</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Fri, 14 Aug 2026 01:11:21 +0000</pubDate>
      <link>https://dev.to/weiwuji/deepseek-open-sourced-its-harness-everything-is-a-plugin-but-the-real-gap-is-in-the-details-3h82</link>
      <guid>https://dev.to/weiwuji/deepseek-open-sourced-its-harness-everything-is-a-plugin-but-the-real-gap-is-in-the-details-3h82</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Pain&lt;/strong&gt;: Today everyone is talking about "DeepSeek open-sourced its Harness" and "everything is a plugin" — and those discussions are valuable. But beyond the buzz, I want to share another angle: a plugin system gives you &lt;em&gt;differentiation space&lt;/em&gt;, not &lt;em&gt;success rates&lt;/em&gt;. What actually separates agents are the less visible details.&lt;br&gt;
&lt;strong&gt;What You'll Learn&lt;/strong&gt;: What DeepSeek Harness is really worth and where its boundaries are — seen from a production system running in real business scenarios. What to steal, and what's actually your moat.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Let's Align on Facts: What Happened Today
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;On August 13, 2026, DeepSeek open-sourced its Harness.&lt;/strong&gt; v0.1 developer preview, MIT license, full source code.&lt;/p&gt;

&lt;p&gt;One sentence summarizes its architecture philosophy: &lt;strong&gt;everything is a plugin&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Models, tools, skills, sessions, sandbox, storage,
Agent Loop, orchestration, UI
        ↓
all replaceable (Cordis plugin system)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: this isn't "you can swap a search tool." &lt;strong&gt;Even how the agent loops, how it spawns sub-agents, how it saves sessions — all replaceable.&lt;/strong&gt; The whole runtime is a Lego base.&lt;/p&gt;

&lt;p&gt;Four run modes = four plugin combinations:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;One-liner&lt;/th&gt;
&lt;th&gt;Who&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Standard&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full tool suite&lt;/td&gt;
&lt;td&gt;Regular agent tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PTC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Model writes code to compose tool calls&lt;/td&gt;
&lt;td&gt;Complex tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Minimal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Only shell + file edit&lt;/td&gt;
&lt;td&gt;Testing models in minimal env&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Creation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent inspects runtime, tries plugins, composes new modes&lt;/td&gt;
&lt;td&gt;🔥 Harness developers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Plus two core designs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Append-only session log&lt;/strong&gt;: every trace flows into one event stream&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-agent built-in&lt;/strong&gt;: Spawn/Fork/Pipeline/Ralph Loop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;You don't need to memorize these terms.&lt;/strong&gt; Just remember one sentence — &lt;strong&gt;DeepSeek turned "how an agent works" into a plugin system you can freely assemble.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Everyone's Talking About "Everything Is a Plugin." Let Me Share Another View.
&lt;/h2&gt;

&lt;p&gt;First, let me be clear: &lt;strong&gt;"everything is a plugin" is genuinely good news&lt;/strong&gt; — for the first time, an agent runtime can be freely assembled, and that's a real liberation for developers.&lt;/p&gt;

&lt;p&gt;But beyond that angle, I want to explore a different view — &lt;strong&gt;after architecture converges, where does the real gap actually lie?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture convergence is inevitable.&lt;/strong&gt; When everyone can plugin-ify tools, loops, and orchestration, those stop being moats. Spawn, Fork, Pipeline, Ralph Loop all have mature precedents — DeepSeek's real innovation is making them config-replaceable plugins.&lt;/p&gt;

&lt;p&gt;An industry expert told InfoQ:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Looking at the full harness pipeline, tool calling, memory management, and task planning directions are basically settled. &lt;strong&gt;The real innovation will happen in the local details.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He named four:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Memory compression&lt;/strong&gt;: accumulated memory needs compressing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conflict cleanup&lt;/strong&gt;: conflicting memories need organizing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Path reuse&lt;/strong&gt;: similar tasks reuse existing planning paths&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan validation&lt;/strong&gt;: post-generation "compile-style" checks (complete error branches? executable ops? steps within permissions?)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;This is where the real gap is.&lt;/strong&gt; Plugin systems provide differentiation space, not success rates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn62psdfb4g1zmvfh1b1q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn62psdfb4g1zmvfh1b1q.png" alt="Architecture converges, gap is in details"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  My Practice: I've Actually Run All Four
&lt;/h2&gt;

&lt;p&gt;Not armchair theory. I've run all four in real business scenarios — just not on DeepSeek Harness, on our own production system.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Memory Compression → My Cognition Distillery
&lt;/h3&gt;

&lt;p&gt;Uncompressed memory drowns the agent.&lt;/p&gt;

&lt;p&gt;My approach is "cognition distillation": after every completed piece of work, I don't keep a log — I &lt;strong&gt;distill into nodes&lt;/strong&gt; (problem + insight + practice + links) into a cognition library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Published articles → distilled into nodes → cognition library (28 nodes)
  ↓
Writing selects precise nodes → articles stay focused
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's memory compression in practice — &lt;strong&gt;not deleting memory, but turning it into a higher-density form.&lt;/strong&gt; DeepSeek confirms this direction.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Conflict Cleanup → My Correction Flywheel
&lt;/h3&gt;

&lt;p&gt;The classic symptom of memory conflict: rules fighting each other, agent doesn't know which to obey.&lt;/p&gt;

&lt;p&gt;My approach is "correction sedimentation": every error → error-ledger → extract lesson → sediment as rule → gate intercepts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Production → audit → errors logged (31 entries)
  → rule sedimentation → gate interception → flywheel spins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key to conflict cleanup isn't cleanup itself — it's &lt;strong&gt;building an error-to-rule conversion pipeline&lt;/strong&gt; so conflicts surface and resolve automatically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg9cgydbrkyazvcrhhgjf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg9cgydbrkyazvcrhhgjf.png" alt="error-ledger data flywheel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Path Reuse → My Scenario Routing
&lt;/h3&gt;

&lt;p&gt;Agents shouldn't plan from scratch every time. Similar tasks follow similar paths.&lt;/p&gt;

&lt;p&gt;My approach is "scenario routing": different scenarios → different agent configs/tool sets, reusing proven paths.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scenario detection → route to matching agent
  → reuse proven path (no replanning from scratch)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Plan Validation → My Physical Pipeline Gates
&lt;/h3&gt;

&lt;p&gt;No validation after planning = letting the agent run naked.&lt;/p&gt;

&lt;p&gt;My approach is "physical pipeline": every task output must pass gate verification before delivery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;validate_article → check_series → article_checker → publish_gate
        ↓
4 gates, all physical, no LLM self-discipline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzwylsecanrchsk4a0we0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzwylsecanrchsk4a0we0.png" alt="The four local gaps"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What to Steal: Three Things DeepSeek Harness Does Better
&lt;/h2&gt;

&lt;p&gt;Despite the gap being in details, DeepSeek Harness does three things better than us. Worth stealing:&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Append-Only Unified Event Stream (Steal This First)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DeepSeek: everything the model sees → one append-only log
  system prompt / reasoning / tool calls / sub-agent orchestration / context injection
Value: shared observability ledger, session forking, replayable evals
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our observability trio (Gate/Audit/Correction) stores separately; their &lt;strong&gt;unified event stream&lt;/strong&gt; is more thorough — &lt;strong&gt;all traces in one stream, evals/debugging/replay all based on it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This directly connects to Trajectory Evals — the evaluator eats traces, and a unified stream makes traces more complete and replayable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0w4zmr2exf1etaufa20w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0w4zmr2exf1etaufa20w.png" alt="Unified event stream"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2️⃣ Tool-Call Pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DeepSeek: tool call = request → Hook → approval → permissions → sandbox → timeout → execute → rewrite → log → UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our tool whitelist is a static check; theirs is a &lt;strong&gt;pluggable pipeline&lt;/strong&gt; — every stage independently replaceable/composable. Security goes from "switch" to "pipeline."&lt;/p&gt;

&lt;h3&gt;
  
  
  3️⃣ Creation Mode Thinking
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DeepSeek: agent can inspect runtime, try plugins, compose new run modes
Meaning: the harness config itself becomes an object the agent can operate on
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is "nurture-style AI" engineering — letting the agent participate in its own config. We already have correction sedimentation; we can go further: &lt;strong&gt;let the agent read/modify its own rule files through tools&lt;/strong&gt; (we have this capability, can systematize it).&lt;/p&gt;




&lt;h2&gt;
  
  
  What NOT to Steal: DeepSeek Harness's Boundaries
&lt;/h2&gt;

&lt;p&gt;Cold water again. Three problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Everything replaceable" ≠ higher success rates&lt;/strong&gt; — plugins give differentiation space; the final effect needs high-quality default plugins, stable composition patterns, and credible eval results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v0.1 migration cost is high&lt;/strong&gt; — core plugins and interfaces will change fast; entering the ecosystem now means absorbing high migration cost&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-agent has no paradigm breakthrough&lt;/strong&gt; — it's a pluggable hierarchical Supervisor-Worker, far from true Swarm (autonomous discovery/negotiation/competition/dynamic takeover)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusion: you can swap the base. You can't stop the flywheel.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Where You Are Now
&lt;/h2&gt;

&lt;p&gt;You're no longer the developer who gets excited every time "everything is a plugin" trends.&lt;/p&gt;

&lt;p&gt;You're becoming the strict engineer who — &lt;strong&gt;sees architecture convergence, watches the local gaps, and validates everything in real business scenarios.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DeepSeek solves "how to build." We prove "how to use" with a production system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remember: the Harness is the base; the production system is the answer. Plugin systems provide differentiation space. What actually decides success — memory compression, conflict cleanup, path reuse, plan validation — only real business scenarios can force you to build.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;About the author: Wu Ji (无记) — AI / Agent / digital transformation practitioner. I only write about things I've actually built and run — no concepts without practice. Follow along, and let's turn cognition into income.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>harness</category>
      <category>engineering</category>
    </item>
    <item>
      <title>DeepSeek Open-Sourced Its Harness (Merged)</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Thu, 13 Aug 2026 14:28:31 +0000</pubDate>
      <link>https://dev.to/weiwuji/deepseek-open-sourced-its-harness-everything-is-a-plugin-but-the-real-gap-is-in-the-details-3j43</link>
      <guid>https://dev.to/weiwuji/deepseek-open-sourced-its-harness-everything-is-a-plugin-but-the-real-gap-is-in-the-details-3j43</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;⚠️ This article has been merged into the updated version: &lt;a href="https://dev.to/weiwuji/deepseek-open-sourced-its-harness-everything-is-a-plugin-but-the-real-gap-is-in-the-details-3h82"&gt;DeepSeek Open-Sourced Its Harness: Everything Is a Plugin, But the Real Gap Is in the Details&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Merged content removed.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>harness</category>
      <category>engineering</category>
    </item>
    <item>
      <title>From Documents to Mechanisms: Onboarding AI Agents with SOP + Checkpoints</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Thu, 13 Aug 2026 13:19:00 +0000</pubDate>
      <link>https://dev.to/weiwuji/from-documents-to-mechanisms-onboarding-checklist-checkpoint-gates-and-rollback-84o</link>
      <guid>https://dev.to/weiwuji/from-documents-to-mechanisms-onboarding-checklist-checkpoint-gates-and-rollback-84o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Pain&lt;/strong&gt;: Your methodology is materialized. Rules layer, facts layer, pipeline layer, memory layer - the files all exist. Then you hit a new problem: the files are written, but does anyone actually read them? You drop the docs into the shared drive, and three days later you ask the new hire "did you read it?" He says yes. Then he submits work that contradicts the rules in the documents. You check the read logs - the file was opened 3 times, 2 minutes each. Can anyone read a 200-page SOP in 2 minutes?&lt;br&gt;
&lt;strong&gt;What You'll Learn&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why "documents written" is not "documents used" - the three gaps that kill every SOP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The landing trio&lt;/strong&gt;: onboarding checklist, checkpoint gates, and a rollback mechanism&lt;/li&gt;
&lt;li&gt;How each piece maps to a real artifact you can build and verify on your own machine today&lt;/li&gt;
&lt;li&gt;Why this trio beats "more training" - and how it makes trust scalable&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Opening: 200 pages of SOP, and the new hire still cannot do the job
&lt;/h2&gt;

&lt;p&gt;In the previous article - &lt;em&gt;From Individual Methodology to Team Assets: The 4-Step Materialization Framework&lt;/em&gt; - we turned the methodology into four layers: Rule Layer, Fact Layer, Pipeline Layer, Memory Layer. The files are all written: &lt;code&gt;STANDING.md&lt;/code&gt;, value practice cards, four physical gates, &lt;code&gt;error-ledger&lt;/code&gt;. Then you discover a new problem: &lt;strong&gt;the files are written, but will the team actually read them?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Real scenario: you put the documents into the shared drive. Three days later you ask the new hire "did you read it?" He says yes. Then he submits output that contradicts every rule in the documents. You open the read log - opened 3 times, 2 minutes each. Can a 200-page SOP be read in 2 minutes?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Between "documents written" and "documents used" lies an entire mechanism.&lt;/strong&gt; Most organizational SOPs die in the same place: the file lies in the shared drive, and nobody ever finishes reading it. Today's cure is the landing trio: &lt;strong&gt;onboarding checklist, checkpoint gates, rollback mechanism&lt;/strong&gt; - turning "did you read it" from a verbal promise into a machine-verifiable gate. These three are not invented for this article; they are components running on my own system, and every command can be reproduced on your machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why "documents written" is not "documents used" - the three gaps
&lt;/h2&gt;

&lt;p&gt;Documents go unused not because people are lazy, but because of three gaps:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gap&lt;/th&gt;
&lt;th&gt;What it looks like&lt;/th&gt;
&lt;th&gt;Root cause&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No path&lt;/td&gt;
&lt;td&gt;The new hire does not know which file to read first&lt;/td&gt;
&lt;td&gt;"What to learn" is guesswork&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No verification&lt;/td&gt;
&lt;td&gt;Nobody can confirm whether it was read&lt;/td&gt;
&lt;td&gt;"Did you learn it" relies on asking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No safety net&lt;/td&gt;
&lt;td&gt;The new hire is afraid to touch anything, scared of breaking it&lt;/td&gt;
&lt;td&gt;"Cost of trying" is unknown&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So SOP rollout is not about more training. It is about filling three holes: &lt;strong&gt;the checklist gives the path, the checkpoint gives verification, the rollback gives safety.&lt;/strong&gt; Let's open each one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F32ynejv98ypim162p4p3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F32ynejv98ypim162p4p3.png" alt="The SOP landing trio: old way (200-page SOP opened 3 times for 2 minutes) transforms into checklist, checkpoint gate, and rollback - new hire productive in one week" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: The onboarding checklist - turn "what to learn" into "tasks that must be checked off"
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem: a document is not a task.&lt;/strong&gt; Anything without a deadline and an acceptance criterion sits at the bottom of every to-do list forever. The new hire is not unwilling to learn; he simply does not know where to start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution: an onboarding checklist.&lt;/strong&gt; Every item is "checkable + produces an artifact + verifiable". This is the checklist running in my own system (&lt;code&gt;/root/shared/onboarding-checklist.md&lt;/code&gt;), first three days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Day 1: read the rules&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Read STANDING.md end to end, write out any one rule verbatim
      (acceptance: cat /root/shared/STANDING.md | head -30)
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Read .hermes.md, restate the publish path
      (acceptance: can state that the legacy publish CLI is banned,
       publishing goes through baoyu-post-to-wechat)
&lt;span class="gu"&gt;## Day 2: run the pipeline&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Run the 4 gates on article-23.md, screenshot the output
      (acceptance: validate_article.py check returns 100/100)
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Read 2 value practice cards, restate the "pitfall and fix" fields
&lt;span class="gu"&gt;## Day 3: produce independently&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Walk through the full publish flow, confirm the draft appears
      (acceptance: draft/batchget returns the title and content is not truncated)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key design is the &lt;strong&gt;acceptance command&lt;/strong&gt;: the artifact of every task must be verifiable by one command, not by "I feel like I learned it". Every item on the checklist eventually flows into a real file. Our task board (&lt;code&gt;/root/shared/writer-task-board.md&lt;/code&gt;) is a living handover list - one agent writes TODO items, another picks them up and updates the status; tasks move through the file, not through anyone's memory. Account handover uses the same mechanism: the handoff guide ships in two waves (four domestic platforms first, three overseas platforms second), and every item states exactly what needs to be provided.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Verification&lt;/strong&gt;: once the new hire checks off the list, asking "did you read it" is pointless - the artifacts are sitting there, open the file and check.&lt;/p&gt;

&lt;p&gt;🩸 &lt;strong&gt;Pitfall&lt;/strong&gt;: the worst checklist is a "reading list" - "recommended reading: XXX". That is not a checklist, that is a bibliography. A bibliography has no acceptance criteria, cannot be checked off, and becomes the second file gathering dust in the shared drive.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Direct value&lt;/strong&gt;: the first step of a one-week handover is not "learning fast", it is "path clarity". On day one the new hire knows what to read first, what to produce, and how to verify it.&lt;/p&gt;

&lt;p&gt;▸ &lt;strong&gt;Cognitive shift&lt;/strong&gt;: a checklist is essentially &lt;strong&gt;turning "what to learn" from an individual judgment into the team's default path&lt;/strong&gt; - once the path is written down, it no longer depends on who is doing the mentoring.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: The checkpoint gate - turn "did you read it" into "is the evidence there"
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem: a checked box can still be a lie.&lt;/strong&gt; "I read it" is an attitude, and attitudes cannot be verified. You ask the new hire "do you understand?" He says yes. Do you believe him or not?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution: the checkpoint does not verify attitude, it verifies evidence.&lt;/strong&gt; The first comment in our gate script says: &lt;strong&gt;never read the LLM's self-report, only read real file evidence&lt;/strong&gt;. That comment was earned by walking into the pitfall - early on we relied on the agent reporting "done", and its self-reports frequently disagreed with actual state; once we switched to file evidence only, false reports died automatically.&lt;/p&gt;

&lt;p&gt;The real artifact is &lt;code&gt;gate-check.sh&lt;/code&gt; (under &lt;code&gt;/root/hermes-harness/scripts/hooks/&lt;/code&gt;). It does not check "did you read STANDING.md"; it checks "is the artifact that STANDING injection produces present" and "is the task-context file created". Evidence missing → blocked; blocked 3 times → escalated to a human. Zero subjective judgment anywhere in the loop.&lt;/p&gt;

&lt;p&gt;The same logic runs harder in the content pipeline: 4 physical gates, and any gate failure means &lt;code&gt;sys.exit(1)&lt;/code&gt; - the publish command never executes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 /root/hermes-harness/scripts/validate_article.py check article-23.md
python3 /root/hermes-harness/scripts/check_series_continuity.py check
python3 /root/hermes-harness/scripts/article_checker.py article-23.md
python3 /root/hermes-harness/gate/publish_gate.py article-23.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real output (I ran the first gate on this very article on my machine):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;check: article-24.md | PASS
body: 3666 chars
quality score: 100/100 (16/16 checks passed)
ALL CHECKS PASSED - article meets the publish standard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Verification&lt;/strong&gt;: any output only counts as qualified after passing every gate - it does not matter how senior you are or who you are; only evidence matters.&lt;/p&gt;

&lt;p&gt;🩸 &lt;strong&gt;Pitfall&lt;/strong&gt;: checkpoints must check "evidence", never "reports". We actually walked into this: the agent self-reported "validation done" while the artifact was missing fields; only the gate scan caught it. Human review has the same flaw - you catch things when you are in a good state and miss them when you are not, so the gate has to be physically enforced.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Direct value&lt;/strong&gt;: quality moves from "I trust you" to "I verify you". The new hire does not need to prove himself; he only needs to produce evidence.&lt;/p&gt;

&lt;p&gt;▸ &lt;strong&gt;Cognitive shift&lt;/strong&gt;: a checkpoint is essentially &lt;strong&gt;turning "trust" from a judgment about a person into a check on evidence&lt;/strong&gt; - trust becomes scalable because it no longer depends on character.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg2arraihesirmx21qpzq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg2arraihesirmx21qpzq.png" alt="The checkpoint gate flow: new hire submits output -&gt; does evidence exist? yes -&gt; next step; no -&gt; blocked, retry, 3 blocks in a row -&gt; escalate to human" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: The rollback mechanism - the confidence that lets new hires dare to try
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem: the checklist gives the path, the checkpoint gives verification, but the new hire still does not dare to touch anything - afraid of breaking it.&lt;/strong&gt; In an organization without rollback, new hires do not dare to change things; if they do not dare to change, they cannot learn; if they cannot learn, the founder still carries everything alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution: rollback = change is reversible.&lt;/strong&gt; Three concrete actions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Version control&lt;/strong&gt;: commit before you change, so you can go back if you break it. Our knowledge base (&lt;code&gt;/root/weiwuji-knowledge-base&lt;/code&gt;) makes every change a commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;
&lt;span class="c"&gt;# fa0676f deep-read notes from 5 WeChat articles&lt;/span&gt;
&lt;span class="c"&gt;# 11888df complete deep-analysis report v1.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Broke something? &lt;code&gt;git revert&lt;/code&gt; brings you back to the last stable version in seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Publishing can be re-uploaded&lt;/strong&gt;: a wrong draft is not a disaster - just re-upload it. The real artifact is &lt;code&gt;reorder_drafts.py&lt;/code&gt;, which re-uploads drafts in reading order; the ledger (&lt;code&gt;publication-ledger.md&lt;/code&gt;) verifies the draft box on every check (&lt;code&gt;draft/batchget&lt;/code&gt;), and when a draft is missing from the box it is marked "confirm needed" and waits for human confirmation - never silently overwritten.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Errors can be logged&lt;/strong&gt;: every rollback is a piece of knowledge. &lt;code&gt;error-ledger.md&lt;/code&gt; logs in four parts: symptom → root cause → fix → status. A real entry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## 2026-08-02 · Daily report trend date shows "?" (fallback fix for missing collected_at)&lt;/span&gt;
&lt;span class="gs"&gt;**Symptom:**&lt;/span&gt; trend date in the daily report shows a question mark
&lt;span class="gs"&gt;**Root cause:**&lt;/span&gt; collected_at field missing
&lt;span class="gs"&gt;**Fix:**&lt;/span&gt; add date fallback logic - when collected_at is missing, fall back to the entry-level timestamp
&lt;span class="gs"&gt;**Status:**&lt;/span&gt; fixed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Verification&lt;/strong&gt;: &lt;code&gt;git revert&lt;/code&gt; is one command; after logging an error, &lt;code&gt;grep&lt;/code&gt; finds the answer in 10 seconds.&lt;/p&gt;

&lt;p&gt;🩸 &lt;strong&gt;Pitfall&lt;/strong&gt;: rollback fails when it is "built but never used". We paid for this: the overseas duplicate-publish incident happened precisely because nobody had recorded "Draft not found actually means the publish succeeded", and the retry logic created duplicates. Now every error is logged the same day it happens.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Direct value&lt;/strong&gt;: rollback compresses the cost of trying from hours to minutes. New hires dare to practice on the real system - and the more they practice, the faster they learn.&lt;/p&gt;

&lt;p&gt;▸ &lt;strong&gt;Cognitive shift&lt;/strong&gt;: rollback is essentially &lt;strong&gt;turning "I broke it" from an incident into a learnable experiment&lt;/strong&gt; - experiments are allowed to fail, as long as every failure is recorded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fucvkyldi8o7h8wzyos79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fucvkyldi8o7h8wzyos79.png" alt="The rollback loop: change ships -&gt; checkpoint fails -&gt; revert to last stable -&gt; log to error ledger -&gt; fix and retry; every rollback produces one error record" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Before vs After: one-week handover vs three months of mentoring
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Before: writing documents&lt;/th&gt;
&lt;th&gt;After: the landing trio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Learning path&lt;/td&gt;
&lt;td&gt;The new hire digs through the shared drive, guessing&lt;/td&gt;
&lt;td&gt;Checklist items checked off one by one, path explicit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Did they learn it&lt;/td&gt;
&lt;td&gt;Ask "do you understand?", he says yes&lt;/td&gt;
&lt;td&gt;Gate verifies evidence, artifacts speak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Something broke&lt;/td&gt;
&lt;td&gt;Wait for the founder to rescue, system stalls&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;git revert&lt;/code&gt; / re-upload, recovery in minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trial mindset&lt;/td&gt;
&lt;td&gt;Afraid, does not dare to touch&lt;/td&gt;
&lt;td&gt;Dares - mistakes can be rolled back and learned from&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;While you are on vacation&lt;/td&gt;
&lt;td&gt;The new hire calls you&lt;/td&gt;
&lt;td&gt;Checklist + gates + rollback run by themselves&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Why the trio beats "more training"
&lt;/h2&gt;

&lt;p&gt;A lot of people assume SOP rollout equals running a few more training sessions. Wrong direction again.&lt;/p&gt;

&lt;p&gt;Training solves "do you know it"; the trio solves "can you, and do you dare". The checklist turns "what to learn" into executable tasks, the checkpoint turns "did you learn it" into verifiable evidence, and rollback turns "trial and error" into a low-cost action - &lt;strong&gt;together, they form a learning environment that allows failure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Go one layer deeper: an organization can give trust to newcomers in two ways. One is betting on character - "I bet you will read it carefully". The other is betting on mechanism - "whether you read it or not, the evidence will speak". Mechanism-based trust does not need a bet, so it scales: a new hire arrives, copy a checklist, run the same gates, enjoy the same rollback net.&lt;/p&gt;

&lt;p&gt;This is the second real question of digital transformation: &lt;strong&gt;the carrier of organizational capability evolves from "documents" to "mechanisms".&lt;/strong&gt; In the previous article we turned experience into documents; in this one we turn documents into mechanisms. Documents go stale; mechanisms self-correct - because every rollback flows back through the error ledger into a new rule.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary: 3 things you can start today
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Write an onboarding checklist&lt;/strong&gt;: break your system's "what to learn" into 3 days of checkable tasks, each with one acceptance command&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change "did you read it" to "is the evidence there"&lt;/strong&gt;: give your key documents a check script, and block when evidence is missing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build one rollback action&lt;/strong&gt;: put the system under git (or equivalent version control) first, then create an error ledger - log today's pitfall today&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do these three, and your documents get "used" for the first time. This is the second foundation stone of digital transformation - &lt;strong&gt;first make the documents get used, then talk about upgrading the organization&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Next article: Digital Transformation in Practice, Part 3 - From SOP to Immunity: Turning Every Incident into Organizational Capability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The trio lets a new hire take over in one week, but incidents will still come. Next we upgrade the error ledger from "personal debugging" to "organizational immunity": incident → log → fix → feed back into the rules, so the system grows a memory every time it makes a mistake - this is what Loop Engineering looks like at the organizational level.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧭 Cognitive Index
&lt;/h2&gt;

&lt;p&gt;🏷️ Entities: onboarding-checklist · gate-check.sh · error-ledger · reorder_drafts.py&lt;br&gt;
💼 Value: SOP rollout · one-week handover · organizational mechanisms&lt;br&gt;
🧠 Cognition: from "writing good documents" to "making documents get used"&lt;/p&gt;

&lt;p&gt;&lt;em&gt;About the author: Wu Ji (无记) — AI / Agent / digital transformation practitioner. Only writes things that actually ran end to end, no concepts for their own sake. Follow along and it just works.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>engineering</category>
      <category>team</category>
    </item>
    <item>
      <title>"Stop Testing Final Answers: Trajectory Evals Are the Truth About Agent Quality"</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Thu, 13 Aug 2026 02:57:01 +0000</pubDate>
      <link>https://dev.to/weiwuji/stop-testing-final-answers-trajectory-evals-are-the-truth-about-agent-quality-39cb</link>
      <guid>https://dev.to/weiwuji/stop-testing-final-answers-trajectory-evals-are-the-truth-about-agent-quality-39cb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Pain&lt;/strong&gt;: You test your agent's final answers — but agents misbehave in the trajectory, not the answer. Wrong tool called, wrong params passed, three loops, a guardrail silently bypassed. Answer all green, process all wrong.&lt;br&gt;
&lt;strong&gt;What You'll Learn&lt;/strong&gt;: 2026's biggest shift in evaluation methodology — from testing outputs to testing trajectories (Trajectory Evals) — plus a copy-paste TrajectoryEvaluator you can run today.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  A Scenario That Makes Your Back Crawl
&lt;/h2&gt;

&lt;p&gt;Here's a real case (it happened in my system):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: check this client's quote history

Agent trajectory (every step logged):
① search_contact("Shanghai Logistics") → 3 candidates found
② get_quote_history(contact_id=007) → empty
③ get_quote_history(contact_id=003) → 12 quotes returned
④ send_email(to=007, content=003's quotes) ← wrong here!
⑤ return "sent"

Final answer: ✅ "Quote history sent to client"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Final answer all green.&lt;/strong&gt; But step ④ sent contact 003's quotes to contact 007 — &lt;strong&gt;wrong recipient.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This isn't my invention. 2026's evaluation community has two consensus-level quotes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Anthropic (2026.01, "Demystifying evals for AI agents"):&lt;/strong&gt;&lt;br&gt;
"We've seen teams with 90% benchmark scores fail in production."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;morphllm:&lt;/strong&gt;&lt;br&gt;
"A final-answer score can be green while the trajectory looped and three turns drifted off policy."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Core insight: output-level testing is blind to agents. You test what it said; the agent's real work happens in what it did.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3mkdcx7ajin8nnax2n1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3mkdcx7ajin8nnax2n1b.png" alt="Trajectory vs Output"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Answer green ≠ trajectory correct: an agent's value lives in the process, not the conclusion.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Testing Trajectories Beats Testing Answers
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Traditional (output-level) testing looks at:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input → Agent → final answer
                  ↑
            only test here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Trajectory evals look at:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input → ①call tool A → ②call tool B → ③decide → ④output
          ↑              ↑            ↑
   right tool?     right params?    loops?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Agent "errors" mostly live in the trajectory, not the answer:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error type&lt;/th&gt;
&lt;th&gt;Answer looks&lt;/th&gt;
&lt;th&gt;Trajectory shows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wrong tool&lt;/td&gt;
&lt;td&gt;normal&lt;/td&gt;
&lt;td&gt;wrong selection ✅caught&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong params&lt;/td&gt;
&lt;td&gt;normal&lt;/td&gt;
&lt;td&gt;bad arguments ✅caught&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infinite loop&lt;/td&gt;
&lt;td&gt;timeout/empty&lt;/td&gt;
&lt;td&gt;loop count anomaly ✅caught&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privilege escape&lt;/td&gt;
&lt;td&gt;normal&lt;/td&gt;
&lt;td&gt;out-of-whitelist access ✅caught&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guardrail bypass&lt;/td&gt;
&lt;td&gt;normal&lt;/td&gt;
&lt;td&gt;skipped check node ✅caught&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;One line: the answer tells you the result; the trajectory tells you why — and agent reliability problems all live in the why.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  My Practice: The error-ledger Data Flywheel
&lt;/h2&gt;

&lt;p&gt;In my system, evaluation isn't a one-time test — it's a continuously spinning data flywheel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Production agent execution
  ↓
Every step logged to audit trail (action/params/result/time)
  ↓
Problem found → error recorded (error-ledger, 31 entries)
  ↓
Lesson extracted → sedimented as rule/skill (writing_lessons, 50 lines)
  ↓
Gate regression intercepts (publish_gate: same error blocked next time)
  ↓
Back to step 1 (flywheel spins)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;This is trajectory evaluation made concrete: not a paper concept, a production system already turning.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpnwx9r89gupdiur4p43.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpnwx9r89gupdiur4p43.png" alt="Data Flywheel"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;error-ledger → lessons → publish_gate: the evaluation flywheel keeps spinning.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Copy-Paste: A TrajectoryEvaluator You Can Run
&lt;/h2&gt;

&lt;p&gt;Here's the trajectory evaluator actually running in my system (simplified, copy-paste ready):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;TrajectoryEvaluator: log every step, detect anomaly patterns&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TrajectoryStep&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;One step in a trajectory&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;                 &lt;span class="c1"&gt;# action: tool/function called
&lt;/span&gt;    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;      &lt;span class="c1"&gt;# params: passed to tool
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;      &lt;span class="c1"&gt;# result: returned by tool
&lt;/span&gt;    &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_factory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Trajectory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;One full execution&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s trajectory&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TrajectoryStep&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_factory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TrajectoryStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; 
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TrajectoryEvaluator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Trajectory evaluator: detect anomaly patterns&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="c1"&gt;# Rule 1: same tool called N+ times consecutively = possible loop
&lt;/span&gt;    &lt;span class="n"&gt;MAX_REPEAT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;whitelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# tool whitelist (least privilege)
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;traj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Trajectory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Evaluate a trajectory, return {score, violations}&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

        &lt;span class="c1"&gt;# Check 1: loop detection
&lt;/span&gt;        &lt;span class="n"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;traj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAX_REPEAT&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAX_REPEAT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# same tool consecutively
&lt;/span&gt;                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_violate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;possible loop: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; called &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAX_REPEAT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Check 2: whitelist detection (privilege escape)
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;traj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;whitelist&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;whitelist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_violate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;privilege escape: called non-whitelisted tool &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Check 3: param sanity (calling tool with empty required params)
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;traj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_quote&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_violate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;param error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; missing recipient&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Score: -20 per violation, start 100
&lt;/span&gt;        &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;passed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;violations&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;trajectory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;traj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_violate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Feed the error-ledger flywheel
&lt;/span&gt;        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  WARNING VIOLATION: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Usage
&lt;/span&gt;&lt;span class="n"&gt;ev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TrajectoryEvaluator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;whitelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_contact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_quote_history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Correct trajectory
&lt;/span&gt;&lt;span class="n"&gt;good&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Trajectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;T1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;good&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_contact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Shanghai Logistics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;candidates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;}]})&lt;/span&gt;
&lt;span class="n"&gt;good&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_quote_history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contact_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quotes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;good&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Wrong trajectory (wrong recipient: step 3 uses 003's data for 007)
&lt;/span&gt;&lt;span class="n"&gt;bad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Trajectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;T2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bad&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_contact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Shanghai Logistics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;candidates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;}]})&lt;/span&gt;
&lt;span class="n"&gt;bad&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_quote_history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contact_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quotes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;bad&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;003&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s quotes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=== Correct trajectory ===&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;good&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;=== Wrong trajectory ===&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bad&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run it and you'll see the difference&lt;/strong&gt;: the correct trajectory scores 100; the wrong one — despite an "all-green" answer — gets caught by the param-sanity rule (&lt;code&gt;send_email missing recipient&lt;/code&gt; style anomaly). That's trajectory evaluation's value.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxjsu2s4lhdk0ebby818.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxjsu2s4lhdk0ebby818.png" alt="TrajectoryEvaluator Architecture"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Loop / whitelist / param sanity: three rule layers score the trajectory.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Wiring Trajectory Evals Into Your System (3 Steps)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Add "trajectory logging" to every tool call
&lt;/h3&gt;

&lt;p&gt;Whatever framework (LangGraph/CrewAI/self-built), the core is &lt;strong&gt;every step records action/params/result&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Define your anomaly rules
&lt;/h3&gt;

&lt;p&gt;Start with my three, then grow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loop (same tool N consecutive times)&lt;/li&gt;
&lt;li&gt;Privilege escape (non-whitelisted tool)&lt;/li&gt;
&lt;li&gt;Param error (missing required / bad format)&lt;/li&gt;
&lt;li&gt;Latency anomaly (single step timeout)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Hook into gate + data flywheel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Low score → block output → human confirms&lt;/li&gt;
&lt;li&gt;Confirmed error → error-ledger → extract rule → back to step 2&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Where You Are Now
&lt;/h2&gt;

&lt;p&gt;You're no longer the optimistic developer who assumes "answer all green means agent is fine."&lt;/p&gt;

&lt;p&gt;You're becoming the strict engineer who &lt;strong&gt;audits the trajectory, scores every action, and sediments every error type into rules.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;2026's biggest evaluation consensus: &lt;strong&gt;test the trajectory, not the answer.&lt;/strong&gt; Because the agent's value lives in the process — answers lie, trajectories don't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remember: an all-green final answer doesn't mean the agent didn't do something wrong. Move evaluation from output to trajectory, and you'll finally see what the agent is really doing.&lt;/strong&gt;&lt;/p&gt;







&lt;p&gt;&lt;em&gt;About the author: Wu Ji (无记) — AI / Agent / digital transformation practitioner. I only write about things I've actually built and run — no concepts without practice. Follow along, and let's turn cognition into income.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>evals</category>
      <category>engineering</category>
    </item>
    <item>
      <title>"DeepSeek-V4 Pro: Everyone Is Benchmarking It, I'm Running It in Real Business Scenarios"</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Thu, 13 Aug 2026 02:56:48 +0000</pubDate>
      <link>https://dev.to/weiwuji/deepseek-v4-pro-everyone-is-benchmarking-it-im-running-it-in-real-business-scenarios-5eih</link>
      <guid>https://dev.to/weiwuji/deepseek-v4-pro-everyone-is-benchmarking-it-im-running-it-in-real-business-scenarios-5eih</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Pain&lt;/strong&gt;: DeepSeek-V4 launched and much of the conversation centers on "near Fable5" and "price is so low" — and that's fair, benchmarks and price are essential selection data. But I want to share what it means for the agent systems you're building in real business scenarios.&lt;br&gt;
&lt;strong&gt;What You'll Learn&lt;/strong&gt;: The 2026 industry shift — from raw benchmark performance to landed value — plus the real signal seen by someone actually running it in real business scenarios.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Let's Align on Facts: What V4 Actually Launched
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;On August 13, 2026, DeepSeek-V4-Pro-0813 officially landed&lt;/strong&gt; (the API version number IS today's date; Hugging Face concurrently published the 1.6T-parameter model). This isn't a roadmap announcement — it just shipped.&lt;/p&gt;

&lt;p&gt;I checked the official API docs. Hard facts, no hype:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Spec&lt;/th&gt;
&lt;th&gt;deepseek-v4-flash&lt;/th&gt;
&lt;th&gt;deepseek-v4-pro&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Version&lt;/td&gt;
&lt;td&gt;V4-Flash-0731&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;V4-Pro-0813 (released today)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parameters&lt;/td&gt;
&lt;td&gt;291B&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.6T&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Context&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1M tokens&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1M tokens&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Max output&lt;/td&gt;
&lt;td&gt;384K&lt;/td&gt;
&lt;td&gt;384K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool calls&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON output&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic API compat&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input (cache hit)&lt;/td&gt;
&lt;td&gt;$0.0028/1M&lt;/td&gt;
&lt;td&gt;$0.0036/1M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input (cache miss)&lt;/td&gt;
&lt;td&gt;$0.14/1M&lt;/td&gt;
&lt;td&gt;$0.435/1M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output&lt;/td&gt;
&lt;td&gt;$0.28/1M&lt;/td&gt;
&lt;td&gt;$0.87/1M&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Benchmark picture (official release framing)&lt;/strong&gt;: DeepSeek-V4-Pro scores &lt;strong&gt;near Fable5, close to SOTA, in the same tier as Grok's top models&lt;/strong&gt; — especially on million-token long-context comprehension and reasoning. The paper is literally titled "DeepSeek-V4: Towards Highly Efficient Million-Token Context Intelligence."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing in CNY (official)&lt;/strong&gt;: V4 Pro cache-miss input is 3 CNY/1M tokens, output 6 CNY/1M (3x Flash); concurrency limit 500 (Flash 2500). &lt;strong&gt;DeepSeek's own positioning is literally "built for Coding and complex Agent tasks" — note the emphasis isn't benchmarks, it's agent tasks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A key detail most people will miss&lt;/strong&gt;: the official announcement says &lt;strong&gt;prices will rise significantly soon&lt;/strong&gt;. The current price is a window of opportunity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmvid7md1kb8gcbwegndg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmvid7md1kb8gcbwegndg.png" alt="Input Price Comparison" width="800" height="385"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Input price ~1/100 of GPT/Claude class (log scale).&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbw5hgsl4sblqy0ccgl89.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbw5hgsl4sblqy0ccgl89.png" alt="DeepSeek V4 Datacard" width="800" height="311"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;1M context + tool calls + $0.0028/1M cache-hit input: agent compute costs just collapsed.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Everyone Is Benchmarking. I Want to Talk About Production Use.
&lt;/h2&gt;

&lt;p&gt;Search for DeepSeek-V4 and you'll find many benchmark comparisons and price analyses — and that's valuable, benchmarks and price are the foundation of any model selection.&lt;/p&gt;

&lt;p&gt;The question I want to explore: &lt;strong&gt;can it survive a real business running 24×7?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But notice the trend shift&lt;/strong&gt;: in 2026, the entire AI industry is moving from "raw benchmark performance" to "landed value." Even DeepSeek's own positioning isn't "how high the benchmark" — it's literally "&lt;strong&gt;built for Coding and complex Agent tasks&lt;/strong&gt;." The vendor itself isn't selling benchmarks anymore; it's selling agent-task capability.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp6uqdqbhhq2qk0pnfotn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp6uqdqbhhq2qk0pnfotn.png" alt="Benchmark vs Production" width="799" height="370"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Benchmarks measure the ceiling; production measures the floor. A model's real value is set by its floor.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  My Practice: Real Business Scenarios Run on V4
&lt;/h2&gt;

&lt;p&gt;The real business scenarios I work on now run &lt;strong&gt;entirely on DeepSeek&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zhi Mo&lt;/strong&gt; (my AI operations partner) → deepseek-v4-flash&lt;/li&gt;
&lt;li&gt;Logistics agent (rates/quotes/reports) → deepseek-v4-flash&lt;/li&gt;
&lt;li&gt;Content pipeline (writing/translation/image captions) → flash + pro&lt;/li&gt;
&lt;li&gt;Multi-platform publishing → orchestrated by Zhi Mo&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Three Real Experiences
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. 1M context isn't a gimmick — it's genuinely less work&lt;/strong&gt;&lt;br&gt;
Before: split long docs into chunks, summarize, build RAG. Now: stuff the whole document in, agent reads everything at once, then works. &lt;strong&gt;I deleted three "chunking" middle steps.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Before: manually chunk the document
&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;split_document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_chunk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;summarize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# After: stuff the whole thing in
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;deepseek-v4-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;full_doc&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;  &lt;span class="c1"&gt;# whole document
&lt;/span&gt;    &lt;span class="n"&gt;thinking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;enabled&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Tool calls are the foundation of agent engineering&lt;/strong&gt;&lt;br&gt;
V4's tool calls + Anthropic API compatibility mean: Claude Code, OpenCode, GitHub Copilot — &lt;strong&gt;change one line of base_url and they use DeepSeek as backend.&lt;/strong&gt; No code rewrite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Cost: from "counting tokens" to "just use it"&lt;/strong&gt;&lt;br&gt;
Cache-hit input at $0.0028/1M — &lt;strong&gt;roughly 1/100 of GPT-class pricing.&lt;/strong&gt; Before, I weighed token costs for every agent task. Now I let agents try more rounds, think more steps.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4g40w0auvcqzqitc0xdc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4g40w0auvcqzqitc0xdc.png" alt="Agent Integration" width="800" height="356"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;One line of base_url swaps your entire agent toolchain to DeepSeek backend.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Differentiating Insight: The Model Is the Engine, Engineering Is the Car
&lt;/h2&gt;

&lt;p&gt;Here's the core of what I want to say.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benchmarks measure engine horsepower. But whether a car drives well depends on the chassis, gearbox, brakes — that's engineering.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Same deepseek-v4-flash:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raw use (pure prompt) → outputs are hit-or-miss&lt;/li&gt;
&lt;li&gt;Engineered use (tool isolation + scene routing + observability + correction sedimentation) → reliable, 24×7&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our practice (covered in previous articles):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scene routing&lt;/strong&gt;: don't make one agent do everything&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool whitelist&lt;/strong&gt;: minimal permissions per scene&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Correction sedimentation&lt;/strong&gt;: never make the same mistake twice&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supervisor orchestration&lt;/strong&gt;: orderly multi-agent collaboration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The cheaper the model, the more valuable engineering becomes.&lt;/strong&gt; Cheap models let you run more agents and more rounds — but without engineering, more runs means more mistakes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjgr4r6i4xz3e2sfcr9qq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjgr4r6i4xz3e2sfcr9qq.png" alt="Full Evaluation View: Benchmarks Are Just the Start" width="799" height="359"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Benchmarks decide entry; real value decides whether it's worth using.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;These practices from real business scenarios apply directly to OPC (one-person companies) and formal company operations&lt;/strong&gt; — whether you're running a business solo or driving digital transformation inside an organization, this engineering toolkit (scene routing + tool whitelist + observability + correction sedimentation) transfers as-is. DeepSeek-V4 collapsing compute costs is exactly the moment to scale it.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmp17rzqmnq5h1s95a25a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmp17rzqmnq5h1s95a25a.png" alt="Model Capability vs Engineering" width="799" height="359"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Model prices drop → engineering value rises. Cheap models enable more agents and more rounds; only engineering makes them stable.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Your Action Items
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Seize the window&lt;/strong&gt;: the official notice says prices will rise significantly. Now is the best time to deploy or migrate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try small first&lt;/strong&gt;: switch one non-critical agent to v4-flash for two weeks; judge by real data, not benchmarks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't use it raw&lt;/strong&gt;: even the strongest model needs scene routing + tool whitelist + observability (our series C and D)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the math&lt;/strong&gt;: calculate your actual scenario at cache-hit prices — it's probably an order of magnitude cheaper than your current setup&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Where You Are Now
&lt;/h2&gt;

&lt;p&gt;You shouldn't be the spectator who "saw the DeepSeek-V4 news, read the benchmarks, closed the tab."&lt;/p&gt;

&lt;p&gt;You should be the practitioner who "sees the opportunity, wires the model into their own system, and validates it with real business."&lt;/p&gt;

&lt;p&gt;The real news about DeepSeek-V4 isn't the benchmark score — &lt;strong&gt;it's an engine that cuts agent production costs by 90%, currently on sale, and about to get more expensive.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The engine has arrived. Is your car built?&lt;/p&gt;







&lt;p&gt;&lt;em&gt;About the author: Wu Ji (无记) — AI / Agent / digital transformation practitioner. I only write about things I've actually built and run — no concepts without practice. Follow along, and let's turn cognition into income.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>deepseek</category>
      <category>agents</category>
      <category>engineering</category>
    </item>
    <item>
      <title>Stop Testing Final Answers: Trajectory Evals (Merged)</title>
      <dc:creator>weiwuji</dc:creator>
      <pubDate>Thu, 13 Aug 2026 01:29:16 +0000</pubDate>
      <link>https://dev.to/weiwuji/stop-testing-final-answers-trajectory-evals-are-the-truth-about-agent-quality-2fkj</link>
      <guid>https://dev.to/weiwuji/stop-testing-final-answers-trajectory-evals-are-the-truth-about-agent-quality-2fkj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;⚠️ This article has been merged into the updated version: &lt;a href="https://dev.to/weiwuji/stop-testing-final-answers-trajectory-evals-are-the-truth-about-agent-quality-39cb"&gt;Stop Testing Final Answers: Trajectory Evals Are the Truth About Agent Quality&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Pain&lt;/strong&gt;: You test your agent's final answers — but agents misbehave in the trajectory, not the answer. Wrong tool called, wrong params passed, three loops, a guardrail silently bypassed. Answer all green, process all wrong.&lt;br&gt;
&lt;strong&gt;What You'll Learn&lt;/strong&gt;: 2026's biggest shift in evaluation methodology — from testing outputs to testing trajectories (Trajectory Evals) — plus a copy-paste TrajectoryEvaluator you can run today.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  A Scenario That Makes Your Back Crawl
&lt;/h2&gt;

&lt;p&gt;Here's a real case (it happened in my system):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: check this client's quote history

Agent trajectory (every step logged):
① search_contact("Shanghai Logistics") → 3 candidates found
② get_quote_history(contact_id=007) → empty
③ get_quote_history(contact_id=003) → 12 quotes returned
④ send_email(to=007, content=003's quotes) ← wrong here!
⑤ return "sent"

Final answer: ✅ "Quote history sent to client"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Final answer all green.&lt;/strong&gt; But step ④ sent contact 003's quotes to contact 007 — &lt;strong&gt;wrong recipient.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This isn't my invention. 2026's evaluation community has two consensus-level quotes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Anthropic (2026.01, "Demystifying evals for AI agents"):&lt;/strong&gt;&lt;br&gt;
"We've seen teams with 90% benchmark scores fail in production."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;morphllm:&lt;/strong&gt;&lt;br&gt;
"A final-answer score can be green while the trajectory looped and three turns drifted off policy."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Core insight: output-level testing is blind to agents. You test what it said; the agent's real work happens in what it did.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3mkdcx7ajin8nnax2n1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3mkdcx7ajin8nnax2n1b.png" alt="Trajectory vs Output" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Answer green ≠ trajectory correct: an agent's value lives in the process, not the conclusion.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Testing Trajectories Beats Testing Answers
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Traditional (output-level) testing looks at:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input → Agent → final answer
                  ↑
            only test here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Trajectory evals look at:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input → ①call tool A → ②call tool B → ③decide → ④output
          ↑              ↑            ↑
   right tool?     right params?    loops?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Agent "errors" mostly live in the trajectory, not the answer:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error type&lt;/th&gt;
&lt;th&gt;Answer looks&lt;/th&gt;
&lt;th&gt;Trajectory shows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wrong tool&lt;/td&gt;
&lt;td&gt;normal&lt;/td&gt;
&lt;td&gt;wrong selection ✅caught&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong params&lt;/td&gt;
&lt;td&gt;normal&lt;/td&gt;
&lt;td&gt;bad arguments ✅caught&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infinite loop&lt;/td&gt;
&lt;td&gt;timeout/empty&lt;/td&gt;
&lt;td&gt;loop count anomaly ✅caught&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privilege escape&lt;/td&gt;
&lt;td&gt;normal&lt;/td&gt;
&lt;td&gt;out-of-whitelist access ✅caught&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guardrail bypass&lt;/td&gt;
&lt;td&gt;normal&lt;/td&gt;
&lt;td&gt;skipped check node ✅caught&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;One line: the answer tells you the result; the trajectory tells you why — and agent reliability problems all live in the why.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  My Practice: The error-ledger Data Flywheel
&lt;/h2&gt;

&lt;p&gt;In my system, evaluation isn't a one-time test — it's a continuously spinning data flywheel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Production agent execution
  ↓
Every step logged to audit trail (action/params/result/time)
  ↓
Problem found → error recorded (error-ledger, 31 entries)
  ↓
Lesson extracted → sedimented as rule/skill (writing_lessons, 50 lines)
  ↓
Gate regression intercepts (publish_gate: same error blocked next time)
  ↓
Back to step 1 (flywheel spins)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;This is trajectory evaluation made concrete: not a paper concept, a production system already turning.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpnwx9r89gupdiur4p43.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpnwx9r89gupdiur4p43.png" alt="Data Flywheel" width="800" height="380"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;error-ledger → lessons → publish_gate: the evaluation flywheel keeps spinning.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Copy-Paste: A TrajectoryEvaluator You Can Run
&lt;/h2&gt;

&lt;p&gt;Here's the trajectory evaluator actually running in my system (simplified, copy-paste ready):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;TrajectoryEvaluator: log every step, detect anomaly patterns&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TrajectoryStep&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;One step in a trajectory&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;                 &lt;span class="c1"&gt;# action: tool/function called
&lt;/span&gt;    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;      &lt;span class="c1"&gt;# params: passed to tool
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;      &lt;span class="c1"&gt;# result: returned by tool
&lt;/span&gt;    &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_factory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Trajectory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;One full execution&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s trajectory&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TrajectoryStep&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_factory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TrajectoryStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; 
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TrajectoryEvaluator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Trajectory evaluator: detect anomaly patterns&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="c1"&gt;# Rule 1: same tool called N+ times consecutively = possible loop
&lt;/span&gt;    &lt;span class="n"&gt;MAX_REPEAT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;whitelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# tool whitelist (least privilege)
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;traj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Trajectory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Evaluate a trajectory, return {score, violations}&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

        &lt;span class="c1"&gt;# Check 1: loop detection
&lt;/span&gt;        &lt;span class="n"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;traj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAX_REPEAT&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAX_REPEAT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# same tool consecutively
&lt;/span&gt;                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_violate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;possible loop: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; called &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAX_REPEAT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Check 2: whitelist detection (privilege escape)
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;traj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;whitelist&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;whitelist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_violate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;privilege escape: called non-whitelisted tool &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Check 3: param sanity (calling tool with empty required params)
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;traj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_quote&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_violate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;param error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; missing recipient&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Score: -20 per violation, start 100
&lt;/span&gt;        &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;passed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;violations&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;trajectory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;traj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_violate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Feed the error-ledger flywheel
&lt;/span&gt;        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  WARNING VIOLATION: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Usage
&lt;/span&gt;&lt;span class="n"&gt;ev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TrajectoryEvaluator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;whitelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_contact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_quote_history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Correct trajectory
&lt;/span&gt;&lt;span class="n"&gt;good&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Trajectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;T1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;good&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_contact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Shanghai Logistics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;candidates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;}]})&lt;/span&gt;
&lt;span class="n"&gt;good&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_quote_history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contact_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quotes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;good&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Wrong trajectory (wrong recipient: step 3 uses 003's data for 007)
&lt;/span&gt;&lt;span class="n"&gt;bad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Trajectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;T2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bad&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_contact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Shanghai Logistics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;candidates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;}]})&lt;/span&gt;
&lt;span class="n"&gt;bad&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_quote_history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contact_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quotes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;bad&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;003&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s quotes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=== Correct trajectory ===&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;good&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;=== Wrong trajectory ===&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bad&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run it and you'll see the difference&lt;/strong&gt;: the correct trajectory scores 100; the wrong one — despite an "all-green" answer — gets caught by the param-sanity rule (&lt;code&gt;send_email missing recipient&lt;/code&gt; style anomaly). That's trajectory evaluation's value.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxjsu2s4lhdk0ebby818.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxjsu2s4lhdk0ebby818.png" alt="TrajectoryEvaluator Architecture" width="800" height="360"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Loop / whitelist / param sanity: three rule layers score the trajectory.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Wiring Trajectory Evals Into Your System (3 Steps)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Add "trajectory logging" to every tool call
&lt;/h3&gt;

&lt;p&gt;Whatever framework (LangGraph/CrewAI/self-built), the core is &lt;strong&gt;every step records action/params/result&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Define your anomaly rules
&lt;/h3&gt;

&lt;p&gt;Start with my three, then grow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loop (same tool N consecutive times)&lt;/li&gt;
&lt;li&gt;Privilege escape (non-whitelisted tool)&lt;/li&gt;
&lt;li&gt;Param error (missing required / bad format)&lt;/li&gt;
&lt;li&gt;Latency anomaly (single step timeout)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Hook into gate + data flywheel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Low score → block output → human confirms&lt;/li&gt;
&lt;li&gt;Confirmed error → error-ledger → extract rule → back to step 2&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Where You Are Now
&lt;/h2&gt;

&lt;p&gt;You're no longer the optimistic developer who assumes "answer all green means agent is fine."&lt;/p&gt;

&lt;p&gt;You're becoming the strict engineer who &lt;strong&gt;audits the trajectory, scores every action, and sediments every error type into rules.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;2026's biggest evaluation consensus: &lt;strong&gt;test the trajectory, not the answer.&lt;/strong&gt; Because the agent's value lives in the process — answers lie, trajectories don't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remember: an all-green final answer doesn't mean the agent didn't do something wrong. Move evaluation from output to trajectory, and you'll finally see what the agent is really doing.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;About the author: Wu Ji (无记) — AI &amp;amp; digitalization practitioner focused on Agent engineering, Loop Engineering, and digital transformation. Practical, hands-on tutorials — follow along and it just works.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>evals</category>
      <category>engineering</category>
    </item>
  </channel>
</rss>
