<?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: ifnodoraemon</title>
    <description>The latest articles on DEV Community by ifnodoraemon (@ifnodoraemon).</description>
    <link>https://dev.to/ifnodoraemon</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%2F4133623%2F013603db-d966-4514-9885-53cc48bb3985.jpg</url>
      <title>DEV Community: ifnodoraemon</title>
      <link>https://dev.to/ifnodoraemon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ifnodoraemon"/>
    <language>en</language>
    <item>
      <title>Building AI Agent Applications from Scratch</title>
      <dc:creator>ifnodoraemon</dc:creator>
      <pubDate>Sun, 20 Sep 2026 06:40:41 +0000</pubDate>
      <link>https://dev.to/ifnodoraemon/building-ai-agent-applications-from-scratch-3c4</link>
      <guid>https://dev.to/ifnodoraemon/building-ai-agent-applications-from-scratch-3c4</guid>
      <description>&lt;h2&gt;
  
  
  What is an AI Agent?
&lt;/h2&gt;

&lt;p&gt;An AI Agent is an AI system capable of &lt;strong&gt;perceiving its environment, making autonomous decisions, and executing actions&lt;/strong&gt;. Unlike traditional single API calls, an Agent can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔄 &lt;strong&gt;Loop execution&lt;/strong&gt;: Continuously adjust actions based on feedback&lt;/li&gt;
&lt;li&gt;🛠️ &lt;strong&gt;Tool calling&lt;/strong&gt;: Search the web, execute code, operate databases&lt;/li&gt;
&lt;li&gt;📋 &lt;strong&gt;Task planning&lt;/strong&gt;: Break down complex goals into actionable steps&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Memory management&lt;/strong&gt;: Maintain &lt;a href="https://blog.llmgo.top/en/articles/context-engineering-guide/" rel="noopener noreferrer"&gt;context&lt;/a&gt; and state over long conversations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture Design
&lt;/h2&gt;

&lt;p&gt;A complete AI Agent system typically includes the following core components:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph LR
    subgraph Core["Core Layer"]
        LLM["Large Language Model"] --- PM["Prompt Manager"]
    end
    subgraph Decision["Decision Layer"]
        Router["Decision Engine"] --- Memory["Memory System"]
    end
    subgraph Tools["Tool Layer"]
        T1["Search"] &amp;amp; T2["Code Execution"] &amp;amp; T3["Database"] &amp;amp; T4["API"]
    end
    Core --&amp;gt; Decision --&amp;gt; Tools&lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;
  
  
  Implementation Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Install Dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langchain langchain-anthropic langgraph tavily-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Define Tools
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_current_time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&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 the current time&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d %H:%M:%S&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_web&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&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 the web to get real-time information&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;tavily&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TavilyClient&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TavilyClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;results&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="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;r&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_python&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Execute Python code and return the result&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&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;python&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;-c&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;capture_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&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;stdout&lt;/span&gt; &lt;span class="ow"&gt;or&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;stderr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Building a State Machine with LangGraph (StateGraph)
&lt;/h3&gt;

&lt;p&gt;Production-grade Agents in 2026 have completely abandoned black-box &lt;code&gt;AgentExecutor&lt;/code&gt; abstractions. Instead, the paradigm has shifted to directed graphs centered around &lt;strong&gt;State Machines&lt;/strong&gt;. This architecture provides extreme controllability and enforces strict data flow (State Schema).&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="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;TypedDict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.prebuilt&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ToolNode&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.messages&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AnyMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add_messages&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_anthropic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatAnthropic&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Strictly define the Agent's global state (State Schema)
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AnyMessage&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;current_task&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;# 2. Node Logic: The Model Reasoning Node
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatAnthropic&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;claude-sonnet-4-6-20260217&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_current_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;search_web&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;execute_python&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;llm_with_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&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;llm_with_tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&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;messages&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="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Build the Directed Graph
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ToolNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# Built-in tool execution node
&lt;/span&gt;
&lt;span class="c1"&gt;# 4. Define Routing and Edges
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_entry_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# If the model's response includes tool_calls, route to tools; otherwise, END
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;tool_calls&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools&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;agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 5. Compile into an Executable Application
&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Execution and Tracing
&lt;/h3&gt;

&lt;p&gt;With the graph architecture, we can precisely trace every state transition step:&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="n"&gt;inputs&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;messages&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;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;Help me find the latest release date for foundation models.&lt;/span&gt;&lt;span class="sh"&gt;"&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;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stream_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;values&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pretty_print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# Clearly inspect every step of Thought -&amp;gt; Action -&amp;gt; Observation
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Model Selection Recommendations
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirements&lt;/th&gt;
&lt;th&gt;Recommended Model&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;Complex Agent tasks&lt;/td&gt;
&lt;td&gt;Claude Opus 4.6&lt;/td&gt;
&lt;td&gt;The strongest Agentic capabilities and Computer Use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daily Agent development&lt;/td&gt;
&lt;td&gt;Claude Sonnet 4.6&lt;/td&gt;
&lt;td&gt;The best balance between speed and intelligence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agents requiring deep reasoning&lt;/td&gt;
&lt;td&gt;GPT-5.4 Thinking&lt;/td&gt;
&lt;td&gt;Transparent thought chains, easier to debug&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-volume production environments&lt;/td&gt;
&lt;td&gt;Gemini 3.1 Flash-Lite&lt;/td&gt;
&lt;td&gt;Best cost-effectiveness&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Make tool descriptions precise&lt;/strong&gt;: LLMs decide when to call tools via their docstrings, the clearer the better.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limit the number of tools&lt;/strong&gt;: Keep it under 10 tools per Agent; too many will decrease selection accuracy. For large-scale external integrations, use the &lt;a href="https://blog.llmgo.top/en/articles/mcp-guide/" rel="noopener noreferrer"&gt;MCP Protocol&lt;/a&gt; for decoupling and standardized tool serving.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add safety guardrails&lt;/strong&gt;: Set explicit permissions and controls for sensitive tools like code execution or database operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement graceful degradation&lt;/strong&gt;: When tool calls fail, the Agent should be able to identify the failure and switch strategies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring and logging&lt;/strong&gt;: Record the input and output of every tool call to facilitate debugging and optimization.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Enterprise-Grade Agent Architecture (Phase 2 Deep Dive)
&lt;/h2&gt;

&lt;p&gt;In real-world production environments, an Agent might encounter API limits, database locks, or asynchronous jobs that take hours to complete. A naive synchronous architecture will instantly collapse (see our &lt;a href="https://blog.llmgo.top/en/articles/agent-runtime-practices/" rel="noopener noreferrer"&gt;7 Runtime Practices for Building AI Agents&lt;/a&gt; for in-depth operational patterns). Here are the most hardcore industry practices:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Cross-Session Persistence &amp;amp; Interruption Recovery (Redis Checkpointer)
&lt;/h3&gt;

&lt;p&gt;To ensure an Agent remembers a user's context even after server restarts, or to pause execution pending human approval (Human-in-the-loop) before high-risk operations (like transferring funds), a Checkpointer is strictly mandatory. The high-concurrency standard for 2026 is using &lt;strong&gt;RedisSaver&lt;/strong&gt;, achieving sub-millisecond state serialization.&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.checkpoint.redis&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RedisSaver&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;redis&lt;/span&gt;

&lt;span class="c1"&gt;# Establish the underlying Redis connection pool
&lt;/span&gt;&lt;span class="n"&gt;redis_conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Redis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;localhost&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6379&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Compile the Graph with Persistence
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;RedisSaver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;redis_conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;interrupt_before&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;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Implement hard interruption before calling tools to wait for approval
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Use thread_id to differentiate user sessions, ensuring absolute concurrency state isolation
&lt;/span&gt;    &lt;span class="n"&gt;config&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;configurable&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;thread_id&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_10086_task_v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;

    &lt;span class="c1"&gt;# The Agent will automatically suspend before the 'tools' node; state is safely stored in Redis
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&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;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Async Event-Driven Orchestration for Long-Running Tasks (Temporal)
&lt;/h3&gt;

&lt;p&gt;Because standard HTTP requests usually timeout after 60 seconds, a synchronous blocking architecture will inevitably crash if your Agent needs to run in the background to scrape 100 webpages and generate a comprehensive financial report. The industry (e.g., OpenAI's Codex architecture) has shifted heavily towards using &lt;strong&gt;Temporal&lt;/strong&gt; as the underlying durable workflow orchestration engine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;High-Concurrency Disaster Recovery Architecture:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway Dispatcher&lt;/strong&gt;: Receives the user request and does not block execution; instead, it immediately returns a UUID ticket (&lt;code&gt;Job_ID&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporal Worker Queue Listener&lt;/strong&gt;: A fleet of background workers listens to the queue, spawning a dedicated LangGraph thread upon receiving the job.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sleep and Automatic Polling&lt;/strong&gt;: When the Agent must wait for an external webpage script to render, it calls &lt;code&gt;await asyncio.sleep(300)&lt;/code&gt;. Temporal physically serializes the entire in-memory state of the Agent into disk storage as a Checkpoint and releases CPU wait resources (100% Crash-safe).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bidirectional State Webhooks&lt;/strong&gt;: Once the task finishes, the final answer is precisely pushed back to the frontend browser via Webhooks or WebSockets.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3. Sandboxed Physical Isolation for Multi-modal &amp;amp; Multi-Agents
&lt;/h3&gt;

&lt;p&gt;For a &lt;code&gt;Coder Agent&lt;/code&gt; with code execution capabilities (like the &lt;code&gt;execute_python&lt;/code&gt; tool from Step 2), it is utterly irresponsible to run its generated code directly on the host machine—this is highly susceptible to Prompt Injection attacks leading to catastrophic &lt;code&gt;rm -rf&lt;/code&gt; scenarios. The only enterprise-grade solution is routing execution via gRPC to completely physically isolated, lightweight MicroVMs (like AWS Firecracker VMs or heavily restricted Docker sidecars) for sandbox execution. Even if an Agent "jailbreaks" and generates malicious commands, it will merely destroy a disposable sandbox with a nanosecond lifecycle, guaranteeing the absolute safety of the host application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In 2026, building excellent AI Agents has long surpassed the infantile phase of "writing two lines of &lt;a href="https://blog.llmgo.top/en/articles/prompt-engineering-guide/" rel="noopener noreferrer"&gt;prompt&lt;/a&gt; and blindly calling an API." To actually deploy large language models to enterprise production lines and withstand millions of malicious requests and traffic spikes, it has evolved into a hyper-dimensional backend discipline merging &lt;strong&gt;exact state-machine topological design, centralized distributed scheduling, microsecond-level cache control, and OS-level sandbox defense&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Frequently Asked Questions (FAQ)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Q1: How can we extend an Agent's capabilities through external protocols?
&lt;/h3&gt;

&lt;p&gt;In practical applications, Agents need to interact with various external systems. We recommend using the &lt;a href="https://blog.llmgo.top/en/articles/mcp-guide/" rel="noopener noreferrer"&gt;MCP Protocol&lt;/a&gt;, which completely decouples tool calling from business logic and provides a standardized extension mechanism. This improves security and simplifies architecture design.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2: How do Agents handle large-scale concurrent requests?
&lt;/h3&gt;

&lt;p&gt;By combining Redis persistence mechanisms with distributed task orchestration engines (such as Temporal), Agents can achieve extremely strong concurrent processing and disaster recovery capabilities. This is much more stable than traditional monolithic synchronous architectures.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://blog.llmgo.top/en/articles/build-ai-agent/" rel="noopener noreferrer"&gt;Nobita Talks AI&lt;/a&gt; on blog.llmgo.top.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Agentic Loops &amp; State Machine Design: From ReAct to Deterministic Control Flows</title>
      <dc:creator>ifnodoraemon</dc:creator>
      <pubDate>Sun, 20 Sep 2026 06:40:30 +0000</pubDate>
      <link>https://dev.to/ifnodoraemon/agentic-loops-state-machine-design-from-react-to-deterministic-control-flows-5bbo</link>
      <guid>https://dev.to/ifnodoraemon/agentic-loops-state-machine-design-from-react-to-deterministic-control-flows-5bbo</guid>
      <description>&lt;p&gt;When software engineers first experiment with Large Language Model (LLM) agents, the textbook pattern feels enchantingly simple: write a system prompt defining available tools, provide the LLM with a &lt;code&gt;while (has_tool_call)&lt;/code&gt; loop, execute whatever functions the model outputs, and feed the results back into the conversation history.&lt;/p&gt;

&lt;p&gt;In small-scale demos or isolated queries, this straightforward &lt;strong&gt;ReAct (Reasoning + Acting)&lt;/strong&gt; loop performs adequately. However, when deployed into serious enterprise production—navigating dozens of heterogeneous tools, flaky external APIs, ill-formed data payloads, and complex multi-branch business logic—an unconstrained ReAct loop almost inevitably collapses.&lt;/p&gt;

&lt;p&gt;The fundamental architectural flaw lies in a profound category mistake: &lt;strong&gt;Large Language Models are probabilistic next-token reasoners, not deterministic state controllers.&lt;/strong&gt; Delegating execution control flow, state transitions, and retry loops entirely to probabilistic sampling is the production equivalent of running an unmonitored infinite loop on live traffic.&lt;/p&gt;

&lt;p&gt;As the flagship opener of &lt;strong&gt;《The Production AI Agent Architect Handbook》&lt;/strong&gt;, this guide deconstructs why raw ReAct loops break at scale and demonstrates how to inject industrial-grade determinism, predictability, and resilience using &lt;strong&gt;Finite State Machines (FSM)&lt;/strong&gt; and &lt;strong&gt;Graph-based Control Flows&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Four Fatal Flaws of Raw ReAct Loops in Production
&lt;/h2&gt;

&lt;p&gt;The classic ReAct framework interleaves model reasoning across three alternating phases: &lt;strong&gt;Thought&lt;/strong&gt; $\rightarrow$ &lt;strong&gt;Action&lt;/strong&gt; $\rightarrow$ &lt;strong&gt;Observation&lt;/strong&gt;. The ubiquitous pseudo-code skeleton looks like this:&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="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="n"&gt;SystemMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserPrompt&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;is_done&lt;/span&gt;&lt;span class="p"&gt;:&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;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_tool_calls&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;call&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;execute_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;messages&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;ToolMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&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;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;is_done&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While elegant in an academic sandbox, this naive loop triggers four catastrophic failure modes under production concurrency:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Infinite Tool Retry Storms
&lt;/h3&gt;

&lt;p&gt;When a downstream service throws an error—such as an HTTP 400 Bad Request due to a schema mismatch—the LLM typically reflects: &lt;em&gt;"The arguments might be slightly malformed, let me try again."&lt;/em&gt; Without deterministic circuit breakers, probabilistic sampling causes the model to regenerate essentially identical requests with superficial variations. Within 30 seconds, an agent can churn through 20 tool calls, burning through hundreds of dollars in API tokens before being forcibly terminated by an HTTP gateway timeout.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Context Snowball &amp;amp; Attention Dilution
&lt;/h3&gt;

&lt;p&gt;Every invocation argument and raw tool response (often sprawling JSON or scraped HTML blobs) is appended indiscriminately to the &lt;code&gt;messages&lt;/code&gt; array. As multi-step tasks reach 15 or 20 iterations, prompt volume easily surges beyond 100,000 tokens.&lt;br&gt;
As documented in our guide to &lt;a href="https://blog.llmgo.top/en/articles/context-engineering-guide/" rel="noopener noreferrer"&gt;Context Engineering in Practice&lt;/a&gt;, this causes extreme latency spikes and triggers the &lt;strong&gt;"Lost in the Middle"&lt;/strong&gt; phenomenon. The LLM loses its attentional grip on the user's primary objectives, hallucinating random tool calls completely decoupled from the original goal.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Cascading Hallucinations &amp;amp; Dirty State Contamination
&lt;/h3&gt;

&lt;p&gt;Without typed contract boundaries between steps, soft tool errors (e.g., an SQL query returning an empty set &lt;code&gt;[]&lt;/code&gt; or unstructured error strings) are ingested directly into the reasoning loop. The model hallucinates plausible-looking placeholder records and feeds that corrupted state into downstream mutating operations—such as executing financial transactions or modifying customer accounts.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Lack of Deterministic Rollback &amp;amp; Escape Hatches
&lt;/h3&gt;

&lt;p&gt;Traditional backend services rely on atomic transaction rollbacks and well-defined fallback handlers when unexpected states occur. In an unconstrained ReAct loop, because no formal transition graph exists, the agent cannot rewind to the last known safe checkpoint, nor can it cleanly hand off control to a human expert. It remains trapped in an erroneous trajectory until budget exhaustion.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. From Freeform Loops to Graph Control: FSM Architecture
&lt;/h2&gt;

&lt;p&gt;The remedy to these failure modes is strict &lt;strong&gt;Separation of Concerns&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Large Language Model is the "Actor" (handling localized reasoning and unstructured extraction within a node), while the Finite State Machine is the "Director" (governing topological transitions, guards, and safety contracts).&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An LLM must never act as both actor and director. The macroscopic routing graph must be defined statically in deterministic code, restricting model agency to strictly bounded state envelopes.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Production State Decomposition
&lt;/h3&gt;

&lt;p&gt;A robust enterprise agent decomposes execution into discrete, verifiable lifecycle states:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;stateDiagram-v2
    [*] --&amp;gt; Idle: User Request Ingested
    Idle --&amp;gt; Planning: Initialize Context Snapshot

    Planning --&amp;gt; ActionSelection: Formulate Sub-task Graph
    Planning --&amp;gt; Fallback: Plan Validation Rejected

    ActionSelection --&amp;gt; ToolExecuting: Dispatched Deterministic Tool
    ActionSelection --&amp;gt; Verification: Direct Synthesis / No Tool Needed
    ActionSelection --&amp;gt; HumanInTheLoop: High-Risk Action Policy Triggered

    HumanInTheLoop --&amp;gt; ToolExecuting: Approval Received via Webhook
    HumanInTheLoop --&amp;gt; Fallback: Rejected / Timeout Window Expired

    ToolExecuting --&amp;gt; Verification: Tool Execution Succeeded
    ToolExecuting --&amp;gt; Fallback: Circuit Breaker Open / Max Retries Met

    Verification --&amp;gt; ActionSelection: Contract Verified &amp;amp; More Steps Left
    Verification --&amp;gt; Completed: Goal Verified &amp;amp; Task Done
    Verification --&amp;gt; Planning: Verification Failed &amp;amp; Re-planning Required

    Fallback --&amp;gt; ActionSelection: Recovered via Alternative Path
    Fallback --&amp;gt; Failed: Unrecoverable Execution Failure

    Completed --&amp;gt; [*]
    Failed --&amp;gt; [*]&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  2. Key Elements of an Agentic State Machine
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Structured State Snapshot&lt;/strong&gt;:&lt;br&gt;
Instead of appending raw message blobs, production systems manage a strongly-typed &lt;code&gt;AgentState&lt;/code&gt; object that cleanly isolates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Immutable Goal&lt;/strong&gt;: The original customer directive, locked against contextual drift.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan Graph&lt;/strong&gt;: Verified step indexes, completed tasks, and pending milestones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Working Scratchpad&lt;/strong&gt;: Ephemeral variables and tool payloads needed only for the immediate step, purged after verification to safeguard the LLM's context window.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Circuit Breaker Registry&lt;/strong&gt;: Real-time tracking of tool invocation frequencies, latencies, and failure counts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transition Matrix &amp;amp; Guard Functions&lt;/strong&gt;:&lt;br&gt;
Every state boundary transition must be guarded by deterministic assertions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For example: &lt;code&gt;ToolExecuting&lt;/code&gt; is strictly barred from leaping back to &lt;code&gt;ActionSelection&lt;/code&gt;. It must flow through &lt;code&gt;Verification&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A transition fires only if &lt;code&gt;pydantic_schema_check(output) == True&lt;/code&gt; and &lt;code&gt;circuit_breaker.is_open() == False&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Checkpoints &amp;amp; Time-Travel Debugging&lt;/strong&gt;:&lt;br&gt;
Every state transition is an immutable event. State snapshots are serialized and persisted into persistent backends (PostgreSQL, SQLite, or Redis). This unlocks two critical capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;True Human-in-the-Loop&lt;/strong&gt;: When high-stakes operations require human approval, worker threads can safely release resources. Once an approver signs off via a webhook, the execution engine rehydrates state instantly via &lt;code&gt;thread_id&lt;/code&gt; and &lt;code&gt;checkpoint_id&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic Trajectory Replay&lt;/strong&gt;: If an agent fails on step 8, engineers can rewind state to step 7, adjust guiding prompts or mock data, and fork execution to reproduce edge cases cleanly. For observability best practices, see &lt;a href="https://blog.llmgo.top/en/articles/agent-observability-debugging/" rel="noopener noreferrer"&gt;Agent Observability &amp;amp; Debugging&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  3. Tool-Calling Defense &amp;amp; Circuit Breakers
&lt;/h2&gt;

&lt;p&gt;In a deterministic architecture, tool invocation is treated not as a trivial &lt;code&gt;try...except&lt;/code&gt; wrapper, but as a layered defensive perimeter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                   ┌───────────────────────────────────────────────┐
                   │               LLM Tool Call                   │
                   └───────────────────────┬───────────────────────┘
                                           ▼
                   ┌───────────────────────────────────────────────┐
                   │  Layer 1: Deterministic Schema Validation    │
                   │  (Strict Pydantic V2 / JSON Schema Check)    │
                   └───────┬───────────────────────────────┬───────┘
                           │ Valid                         │ Invalid
                           ▼                               ▼
      ┌────────────────────────────────────┐     ┌─────────────────┐
      │  Layer 2: Circuit Breaker Check    │     │ Inject Schema   │
      │  (Inspect if target tool is OPEN)  │     │ Error Prompt    │
      └───────┬────────────────────┬───────┘     └────────┬────────┘
              │ Closed (Normal)    │ Open (Tripped)       │ (Self-Correct)
              ▼                    ▼                      ▼
      ┌───────────────┐    ┌─────────────────┐   ┌─────────────────┐
      │ Execute Tool  │    │ Route to        │   │ Retry in Current│
      │ Real API Call │    │ Fallback Tool   │   │ Node (Max 2)    │
      └───────┬───────┘    └─────────────────┘   └─────────────────┘
              │ Exception
              ▼
      ┌────────────────────────────────────┐
      │ Increment Failure Counter          │
      │ If failures &amp;gt;= 3 -&amp;gt; Open Circuit   │
      └────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Strict Schema Enforcement and Bounded Self-Correction
&lt;/h3&gt;

&lt;p&gt;Models frequently commit trivial formatting errors: passing timestamps as raw strings, omitting required keys, or providing floating-point values formatted with dollar signs.&lt;br&gt;
Forwarding invalid parameters to downstream production databases wastes backend compute and yields obscure error messages that further mislead the model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architectural Best Practice&lt;/strong&gt;:&lt;br&gt;
Deploy a strict Pydantic V2 schema validation layer ahead of API execution. When validation fails, &lt;strong&gt;intercept the error locally within the runtime&lt;/strong&gt;. Feed a precise correction prompt (e.g., &lt;code&gt;"Field 'limit' must be an integer between 1 and 50, but received 'unlimited'. Please fix this parameter."&lt;/code&gt;) directly to the decision node, capping local corrections at two retries before escalating.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Stateful Circuit Breakers
&lt;/h3&gt;

&lt;p&gt;When an external tool suffers downstream degradation or network outages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Closed&lt;/strong&gt;: Normal operations. Tool calls are dispatched without restriction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open&lt;/strong&gt;: The tool has failed repeatedly (e.g., 3 consecutive failures). The runtime intercepts further attempts immediately, bypassing the faulty service and directing the FSM to an alternative degraded workflow (e.g., switching from real-time database queries to read-only replica caches).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Half-Open&lt;/strong&gt;: Following a cooling window, a single probe invocation is permitted. A successful call resets the breaker to Closed; continued failure resets the backoff timer.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  4. Production Implementation: A Resilient Python State Machine Engine
&lt;/h2&gt;

&lt;p&gt;The following standalone Python 3.11+ implementation provides a production-grade agent state machine engine with Pydantic V2 schema validation, stateful circuit breakers, and deterministic fallback handling without heavy framework abstractions:&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;
deterministic_agent_fsm.py
Production-grade deterministic agent FSM engine featuring circuit breakers,
strict Pydantic schema validation, and isolated working scratchpads.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Enum&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;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Callable&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;List&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ValidationError&lt;/span&gt;

&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%(asctime)s [%(levelname)s] %(message)s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AgentFSM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# ==========================================================
# 1. State and Data Model Definitions
# ==========================================================
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NodeState&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;Enum&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;IDLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IDLE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;PLANNING&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PLANNING&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;ACTION_SELECT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ACTION_SELECT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;TOOL_EXECUTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TOOL_EXECUTION&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;VERIFICATION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VERIFICATION&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;FALLBACK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FALLBACK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;TERMINAL_SUCCESS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TERMINAL_SUCCESS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;TERMINAL_FAILED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TERMINAL_FAILED&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SearchDatabaseArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt; &lt;span class="n"&gt;min_length&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="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Target search query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ge&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;le&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Max returned results (1-50)&lt;/span&gt;&lt;span class="sh"&gt;"&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;ToolResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&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="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;error_message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&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="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;user_goal&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;current_step&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;max_steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="n"&gt;scratchpad&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;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="o"&gt;=&lt;/span&gt; &lt;span class="nc"&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="n"&gt;final_output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&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="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;circuit_failures&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="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&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;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;circuit_max_failures&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;


&lt;span class="c1"&gt;# ==========================================================
# 2. External Service Simulator with Injected Failures
# ==========================================================
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExternalServiceSimulator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Simulates an external database service to verify circuit breaker behaviors.&lt;/span&gt;&lt;span class="sh"&gt;"""&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;failure_trigger_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&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;call_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;failure_trigger_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;failure_trigger_count&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_database&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;query&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;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="c1"&gt;# Injects deliberate connection timeouts to trigger circuit tripping
&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;call_count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&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;failure_trigger_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ConnectionError&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;Database cluster timeout (Attempt &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;call_count&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="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;status&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;ok&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;items&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Result #&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; for &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&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;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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;limit&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;# ==========================================================
# 3. Deterministic Finite State Machine Engine
# ==========================================================
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DeterministicAgentFSM&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;__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;user_goal&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;db_service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ExternalServiceSimulator&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;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_goal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user_goal&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;db_service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db_service&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;current_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IDLE&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;history&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="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&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;transition_to&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;next_state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&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;Transition: [&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;current_state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;] -&amp;gt; [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;next_state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&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;if&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&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; (Reason: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reason&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="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&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;history&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="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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; -&amp;gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;next_state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next_state&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_circuit_open&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;tool_name&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;failures&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;circuit_failures&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="n"&gt;tool_name&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;failures&lt;/span&gt; &lt;span class="o"&gt;&amp;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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;circuit_max_failures&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;record_tool_failure&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;tool_name&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;circuit_failures&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tool_name&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;circuit_failures&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="n"&gt;tool_name&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="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warning&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;Tool [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;] failure count: &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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;circuit_failures&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tool_name&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="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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;circuit_max_failures&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reset_tool_failure&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;tool_name&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tool_name&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;circuit_failures&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;circuit_failures&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="c1"&gt;# ---------------- Node Execution Handlers ----------------
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;step_idle&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;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&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;Received goal: &lt;/span&gt;&lt;span class="sh"&gt;'&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_goal&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PLANNING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Goal initialized&lt;/span&gt;&lt;span class="sh"&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;step_planning&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_step&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Decomposing goal into structured verifiable steps...&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;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ACTION_SELECT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Plan ready&lt;/span&gt;&lt;span class="sh"&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;step_action_select&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_step&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_step&lt;/span&gt; &lt;span class="o"&gt;&amp;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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_steps&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;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FALLBACK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Step budget exceeded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="c1"&gt;# Verify circuit breaker condition
&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="nf"&gt;is_circuit_open&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_database&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Circuit breaker is OPEN for &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;search_database&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;. Execution intercepted.&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;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FALLBACK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Circuit breaker tripped&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="c1"&gt;# Emulate LLM tool dispatch with arguments
&lt;/span&gt;        &lt;span class="n"&gt;mock_model_raw_args&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;query&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;production_incident_report&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;limit&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="c1"&gt;# Layer 1: Strict Pydantic schema validation
&lt;/span&gt;        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;validated_args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SearchDatabaseArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;mock_model_raw_args&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scratchpad&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;action&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;search_database&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;args&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;validated_args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model_dump&lt;/span&gt;&lt;span class="p"&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;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TOOL_EXECUTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Schema validation passed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;ValidationError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&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;Schema validation failed: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;()&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PLANNING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Schema repair requested&lt;/span&gt;&lt;span class="sh"&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;step_tool_execution&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;last_action&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scratchpad&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="n"&gt;tool_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_action&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;action&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_action&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;args&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&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;Executing tool &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; with args: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;args&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="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;raw_response&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;db_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search_database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&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;reset_tool_failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;last_action&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ToolResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;raw_response&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;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VERIFICATION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tool executed successfully&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&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;Execution error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;err&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;record_tool_failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;last_action&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ToolResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&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;error_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&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="nf"&gt;is_circuit_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_name&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;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FALLBACK&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;Tool [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;] reached max failure threshold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&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;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ACTION_SELECT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Retry with remaining budget&lt;/span&gt;&lt;span class="sh"&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;step_verification&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;last_action&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scratchpad&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="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ToolResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_action&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;result&lt;/span&gt;&lt;span class="sh"&gt;"&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;result&lt;/span&gt; &lt;span class="ow"&gt;and&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;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Verification passed: Structured data confirmed.&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;final_output&lt;/span&gt; &lt;span class="o"&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;Successfully fetched &lt;/span&gt;&lt;span class="si"&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; items.&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="nf"&gt;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TERMINAL_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Goal completed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Verification failed: Data incomplete.&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;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PLANNING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Re-planning required&lt;/span&gt;&lt;span class="sh"&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;step_fallback&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;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Entering FALLBACK node. Triggering graceful degradation...&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;final_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Gracefully degraded: Returning cached incident summaries.&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="nf"&gt;transition_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TERMINAL_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Recovered via Fallback degradation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# ---------------- FSM Execution Loop ----------------
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&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="o"&gt;-&amp;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;handlers&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;NodeState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Callable&lt;/span&gt;&lt;span class="p"&gt;[[],&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IDLE&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;step_idle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PLANNING&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;step_planning&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ACTION_SELECT&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;step_action_select&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TOOL_EXECUTION&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;step_tool_execution&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VERIFICATION&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;step_verification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FALLBACK&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;step_fallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;while&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;current_state&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TERMINAL_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NodeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TERMINAL_FAILED&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handlers&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&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;Unhandled FSM state: &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;current_state&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="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&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;FSM Terminated at [&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;current_state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]. Output: &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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;final_output&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="k"&gt;return&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;final_output&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&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="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;--- [Test Scenario: Flaky Service Tripping Circuit Breaker to Fallback] ---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;failing_service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ExternalServiceSimulator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;failure_trigger_count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DeterministicAgentFSM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;user_goal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Query latest production diagnosis report&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;db_service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;failing_service&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&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;--- Execution Trajectory Trace ---&lt;/span&gt;&lt;span class="sh"&gt;"&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;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transition&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Step &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="n"&gt;d&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;transition&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Execution Log Trace
&lt;/h3&gt;

&lt;p&gt;Executing the script yields a clean, audited, and deterministic transition trace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2026-09-20 10:15:01 [INFO] Received goal: 'Query latest production diagnosis report'
2026-09-20 10:15:01 [INFO] Transition: [IDLE] -&amp;gt; [PLANNING] (Reason: Goal initialized)
2026-09-20 10:15:01 [INFO] Decomposing goal into structured verifiable steps...
2026-09-20 10:15:01 [INFO] Transition: [PLANNING] -&amp;gt; [ACTION_SELECT] (Reason: Plan ready)
2026-09-20 10:15:01 [INFO] Transition: [ACTION_SELECT] -&amp;gt; [TOOL_EXECUTION] (Reason: Schema validation passed)
2026-09-20 10:15:01 [INFO] Executing tool 'search_database' with args: {'query': 'production_incident_report', 'limit': 3}
2026-09-20 10:15:01 [ERROR] Execution error: Database cluster timeout (Attempt 1)
2026-09-20 10:15:01 [WARNING] Tool [search_database] failure count: 1/3
2026-09-20 10:15:01 [INFO] Transition: [TOOL_EXECUTION] -&amp;gt; [ACTION_SELECT] (Reason: Retry with remaining budget)
2026-09-20 10:15:01 [INFO] Transition: [ACTION_SELECT] -&amp;gt; [TOOL_EXECUTION] (Reason: Schema validation passed)
2026-09-20 10:15:01 [ERROR] Execution error: Database cluster timeout (Attempt 2)
2026-09-20 10:15:01 [WARNING] Tool [search_database] failure count: 2/3
2026-09-20 10:15:01 [INFO] Transition: [TOOL_EXECUTION] -&amp;gt; [ACTION_SELECT] (Reason: Retry with remaining budget)
2026-09-20 10:15:01 [INFO] Transition: [ACTION_SELECT] -&amp;gt; [TOOL_EXECUTION] (Reason: Schema validation passed)
2026-09-20 10:15:01 [ERROR] Execution error: Database cluster timeout (Attempt 3)
2026-09-20 10:15:01 [WARNING] Tool [search_database] failure count: 3/3
2026-09-20 10:15:01 [INFO] Transition: [TOOL_EXECUTION] -&amp;gt; [FALLBACK] (Reason: Tool [search_database] reached max failure threshold)
2026-09-20 10:15:01 [INFO] Entering FALLBACK node. Triggering graceful degradation...
2026-09-20 10:15:01 [INFO] Transition: [FALLBACK] -&amp;gt; [TERMINAL_SUCCESS] (Reason: Recovered via Fallback degradation)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a standard ReAct loop without circuit breakers, the agent would continue churning through attempts until hitting gateway timeouts. In contrast, the FSM trips immediately upon hitting the failure threshold, routing execution safely to the &lt;code&gt;FALLBACK&lt;/code&gt; degradation node.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Architectural Memory Isolation: Scratchpads vs Checkpointers
&lt;/h2&gt;

&lt;p&gt;A critical error in enterprise agent design is appending every raw tool payload to a singular conversational history. In state machine architecture, memory must be stratified:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Memory Tier&lt;/th&gt;
&lt;th&gt;Stored Contents&lt;/th&gt;
&lt;th&gt;Lifecycle&lt;/th&gt;
&lt;th&gt;Context Window Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Working Scratchpad&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Raw intermediate tool outputs, scraped HTML, unparsed JSON&lt;/td&gt;
&lt;td&gt;Ephemeral (alive only during node execution; discarded or distilled upon transition)&lt;/td&gt;
&lt;td&gt;Injected only into localized single-step LLM calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;State Checkpointer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sub-task progress, verified plan graphs, entity state dictionaries&lt;/td&gt;
&lt;td&gt;Persistent across task execution (persisted to PostgreSQL / Redis)&lt;/td&gt;
&lt;td&gt;Distilled into compact summaries during re-planning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Episodic Long-Term Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cross-session user preferences, learned historical workflows, corporate knowledge bases&lt;/td&gt;
&lt;td&gt;Permanent storage across user sessions (Vector DBs / Knowledge Graphs)&lt;/td&gt;
&lt;td&gt;Injected dynamically via Top-K semantic retrieval&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For deep dives into external retrieval and context hygiene, explore our practical guide on &lt;a href="https://blog.llmgo.top/en/articles/rag-in-practice/" rel="noopener noreferrer"&gt;Enterprise RAG in Practice&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. The Production AI Agent Architect Handbook Roadmap
&lt;/h2&gt;

&lt;p&gt;Deterministic control flows form the &lt;strong&gt;first essential pillar&lt;/strong&gt; of production-grade agent engineering. Once the deterministic skeleton is locked in, advanced reasoning capabilities can be deployed safely without jeopardizing business reliability.&lt;/p&gt;

&lt;p&gt;Explore the complete curriculum across the 10 chapters of this handbook:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://blog.llmgo.top/en/articles/agent-loop-state-machine/" rel="noopener noreferrer"&gt;Part 1 (Current) · Agentic Loops &amp;amp; State Machine Design: From ReAct to Deterministic Control Flows&lt;/a&gt;&lt;/strong&gt;
&lt;em&gt;Foundational state machine topologies, transition guards, and circuit breaker patterns.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://blog.llmgo.top/en/articles/build-ai-agent/" rel="noopener noreferrer"&gt;Part 2 · Building an AI Agent from Scratch: ReAct Loops &amp;amp; Architecture&lt;/a&gt;&lt;/strong&gt;
&lt;em&gt;Test-driven engineering for autonomous agent cores and tool orchestrators.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://blog.llmgo.top/en/articles/agent-runtime-practices/" rel="noopener noreferrer"&gt;Part 3 · 7 Production Runtime Practices for AI Agents&lt;/a&gt;&lt;/strong&gt;
&lt;em&gt;Production runtime patterns, timeout debouncing, and concurrency isolation.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://blog.llmgo.top/en/articles/mcp-guide/" rel="noopener noreferrer"&gt;Part 4 · Deep Dive into Model Context Protocol (MCP): The USB-C for AI&lt;/a&gt;&lt;/strong&gt;
&lt;em&gt;Anthropic's standardized protocol for custom tool servers and secure enterprise governance.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://blog.llmgo.top/en/articles/skills-guide/" rel="noopener noreferrer"&gt;Part 5 · Deep Dive into Skills: Giving AI Coding Agents a Specialized Brain&lt;/a&gt;&lt;/strong&gt;
&lt;em&gt;Progressive context loading mechanisms and modular coding agent architectures.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://blog.llmgo.top/en/articles/browser-use-agent-architecture/" rel="noopener noreferrer"&gt;Part 6 · Under the Hood of Browser-use: DOM Distillation &amp;amp; Vision Grounding&lt;/a&gt;&lt;/strong&gt;
&lt;em&gt;Crossing from API calls to visual web automation with 100k+ star architecture insights.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://blog.llmgo.top/en/articles/agent-reflection-self-correction/" rel="noopener noreferrer"&gt;Part 7 · Evolving Models at Runtime: From Basic Reflection to MCTS-based Test-Time Compute&lt;/a&gt;&lt;/strong&gt;
&lt;em&gt;Reflexion loops, iterative verification, and Monte Carlo Tree Search at inference time.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://blog.llmgo.top/en/articles/agent-orchestration-evals/" rel="noopener noreferrer"&gt;Part 8 · 2026 AI Paradigm Shift: Distributed Agent Orchestration &amp;amp; Evals&lt;/a&gt;&lt;/strong&gt;
&lt;em&gt;Multi-agent swarms, combating compounding error rates, and automated benchmark evals.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://blog.llmgo.top/en/articles/agent-observability-debugging/" rel="noopener noreferrer"&gt;Part 9 · Agent Observability &amp;amp; Debugging: From Black Box to White Box&lt;/a&gt;&lt;/strong&gt;
&lt;em&gt;OpenTelemetry, LangSmith, and trajectory replay for complete execution transparency.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://blog.llmgo.top/en/articles/environment-scaling-agent-guide/" rel="noopener noreferrer"&gt;Part 10 · How Environment Scaling Reshapes Autonomous Agents: Sandboxing &amp;amp; RL&lt;/a&gt;&lt;/strong&gt;
&lt;em&gt;Post-training environment exploration, zero-escape container sandboxing, and benchmark dominance.&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Frequently Asked Questions (FAQ)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Q1: Given that modern LLMs exhibit impressive autonomous reasoning, why constrain them with rigid state machines rather than using fully autonomous loops?
&lt;/h3&gt;

&lt;p&gt;The reasoning capability of LLMs is mathematically rooted in probabilistic token sampling, which cannot provide &lt;strong&gt;deterministic safety guarantees&lt;/strong&gt;. In production environments, tasks frequently perform mutating state modifications across enterprise backends (e.g., executing debit payments, writing cloud configs, or deleting records). If an LLM is granted unconstrained control over state flow, unexpected network jitter, boundary inputs, or prompt injection can trap the model in repetitive oscillations or bypass mandatory security verification steps. A Finite State Machine (FSM) establishes code-level immutable edges for business policies while delegating flexible semantic reasoning to nodes inside safe sandboxes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2: How does a state machine prevent context window explosion and attention decay across long-running multi-step workflows?
&lt;/h3&gt;

&lt;p&gt;Through strict &lt;strong&gt;separation between ephemeral scratchpads and persistent checkpointers&lt;/strong&gt;. In an FSM, large raw payloads produced by tool executions (such as 100KB database outputs or raw web pages) exist only within the current node's localized working scratchpad. Before transitioning to downstream nodes, a verification step condenses raw data into concise typed summaries or entity dictionaries stored in the state checkpointer. Detailed raw traces are offloaded directly to asynchronous telemetry collectors (e.g., Langfuse / OpenTelemetry), ensuring the active context window remains lean and constant throughout multi-step execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3: How should Human-in-the-Loop (HITL) workflows be architected within an agent state machine without blocking backend workers?
&lt;/h3&gt;

&lt;p&gt;Through &lt;strong&gt;persistent checkpointer serialization coupled with asynchronous event webhooks&lt;/strong&gt;. When an FSM routes to a &lt;code&gt;HumanInTheLoop&lt;/code&gt; node for high-risk approvals, the engine serializes the complete &lt;code&gt;AgentState&lt;/code&gt; snapshot to a persistent store (e.g., PostgreSQL or Redis) tagged with a &lt;code&gt;session_id&lt;/code&gt; and &lt;code&gt;checkpoint_id&lt;/code&gt;. The active worker thread or coroutine immediately releases its resources back to the pool. When a human reviewer approves or rejects the action via Slack, enterprise messaging, or an admin portal, an incoming webhook retrieves the snapshot by &lt;code&gt;checkpoint_id&lt;/code&gt;, restores the exact execution context on an available worker, and resumes execution seamlessly without state loss.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://blog.llmgo.top/en/articles/agent-loop-state-machine/" rel="noopener noreferrer"&gt;Nobita Talks AI&lt;/a&gt; on blog.llmgo.top.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Under the Hood of Browser-use (100k+ Stars): DOM Tree Distillation, Vision Grounding, and Production Web Agents</title>
      <dc:creator>ifnodoraemon</dc:creator>
      <pubDate>Sun, 20 Sep 2026 05:05:08 +0000</pubDate>
      <link>https://dev.to/ifnodoraemon/under-the-hood-of-browser-use-100k-stars-dom-tree-distillation-vision-grounding-and-5363</link>
      <guid>https://dev.to/ifnodoraemon/under-the-hood-of-browser-use-100k-stars-dom-tree-distillation-vision-grounding-and-5363</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: The Death of Fragile RPA and Selector-Based Automation
&lt;/h2&gt;

&lt;p&gt;For more than a decade, web automation—spanning web scraping, QA regression testing, and Robotic Process Automation (RPA)—has been plagued by a fundamental failure mode: &lt;strong&gt;brittle XPath and CSS selectors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Whenever frontend teams refactor component trees, re-nest a container &lt;code&gt;div&lt;/code&gt;, or adopt utility-first CSS frameworks with randomized hash classes (e.g. &lt;code&gt;class="flex_a8f9z bg-blue_39kd"&lt;/code&gt;), carefully maintained Playwright or Selenium scripts break without warning.&lt;/p&gt;

&lt;p&gt;Entering 2026, this fragile paradigm has been replaced by autonomous web agents. Pioneered by projects like &lt;strong&gt;&lt;a href="https://github.com/browser-use/browser-use" rel="noopener noreferrer"&gt;Browser-use&lt;/a&gt;&lt;/strong&gt;, which quickly surpassed &lt;strong&gt;100,000 stars on GitHub&lt;/strong&gt;, automation has shifted toward multimodal cognitive interaction. Instead of matching brittle DOM paths, the model navigates the web like a human: &lt;strong&gt;perceiving rendered screenshots with its eyes, understanding interactive semantics with its brain, planning multi-step actions, and self-healing when encountering unexpected modals or bot challenges.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph LR
    subgraph Fragile Traditional Automation
        A1["Dynamic Target Webpage"] --&amp;gt; A2["Hardcoded XPath/CSS Selectors"] --&amp;gt; A3["Frontend Refactor (Class Changed)"] --&amp;gt; A4["❌ Script Throws Execution Error"]
    end
    subgraph Cognitive Autonomous Browser-use
        B1["Dynamic Target Webpage"] --&amp;gt; B2["DOM Pruning + Set-of-Mark (SoM) Overlays"] --&amp;gt; B3["Multimodal LLM Reasoning Engine"] --&amp;gt; B4["Dynamic Adaptive Actions"] --&amp;gt; B5["✅ Resilient Task Completion"]
    end&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;This article deconstructs the architectural foundations of Browser-use, explaining how it mitigates token explosion, eliminates visual coordinate drift, evades bot detection, and executes multi-step enterprise workflows.&lt;/p&gt;




&lt;h2&gt;
  
  
  I. Dual-Modal Perception Core: DOM Tree Distillation &amp;amp; Set-of-Mark Grounding
&lt;/h2&gt;

&lt;p&gt;Passing raw modern Single Page Application (SPA) HTML directly into an LLM context window is disastrous: pages often span megabytes of minified code, consuming tens of thousands of tokens and diluting the model with extraneous &lt;code&gt;script&lt;/code&gt;, &lt;code&gt;style&lt;/code&gt;, and &lt;code&gt;svg&lt;/code&gt; metadata.&lt;/p&gt;

&lt;p&gt;Browser-use resolves this with an efficient &lt;strong&gt;dual-modal perception pipeline&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TD
    A["Webpage Rendering (Playwright Chromium)"] --&amp;gt; B["Dual Extraction: DOM Snapshot + High-Res Viewport Screenshot"]

    subgraph Text Modality: Heuristic DOM Tree Distillation
        B --&amp;gt; C1["Strip scripts, styles, SVGs, and hidden elements"]
        C1 --&amp;gt; C2["Extract interactive nodes (button, input, a, select)"]
        C2 --&amp;gt; C3["Compute element BoundingBoxes &amp;amp; viewport visibility"]
        C3 --&amp;gt; C4["Distill into lightweight semantic tree (~5KB - 15KB)"]
    end

    subgraph Vision Modality: Set-of-Mark (SoM) Coordinate Grounding
        B --&amp;gt; D1["Render bounding boxes on high-res screenshot"]
        D1 --&amp;gt; D2["Assign unique numerical badge IDs to interactive elements"]
        D2 --&amp;gt; D3["Generate Set-of-Mark (SoM) visual screenshot"]
    end

    C4 --&amp;gt; E["Multimodal LLM Unified Context"]
    D3 --&amp;gt; E&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  1. Heuristic DOM Tree Pruning
&lt;/h3&gt;

&lt;p&gt;Browser-use injects a specialized traversal script into the browser runtime to prune non-essential DOM structures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Visibility Filtering&lt;/strong&gt;: Evaluates computed styles (&lt;code&gt;display === 'none'&lt;/code&gt;, &lt;code&gt;visibility === 'hidden'&lt;/code&gt;, &lt;code&gt;opacity === '0'&lt;/code&gt;) and discards nodes outside the active viewport.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metadata Stripping&lt;/strong&gt;: Purges all &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tags alongside SVG paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic Flattening&lt;/strong&gt;: Collapses non-semantic wrapper &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; chains, preserving only nodes that contain meaningful text or interactive accessibility attributes (&lt;code&gt;aria-label&lt;/code&gt;, &lt;code&gt;placeholder&lt;/code&gt;, &lt;code&gt;role&lt;/code&gt;, &lt;code&gt;href&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result&lt;/strong&gt;: Raw HTML trees shrinking from 2MB+ down to an information-dense representation of &lt;strong&gt;1,500 to 3,000 tokens&lt;/strong&gt;. For strategies on managing runtime context budgets, review our &lt;a href="https://blog.llmgo.top/en/articles/context-engineering-guide/" rel="noopener noreferrer"&gt;Context Engineering Guide&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Set-of-Mark (SoM) Visual Grounding
&lt;/h3&gt;

&lt;p&gt;Predicting exact pixel coordinates (e.g. &lt;code&gt;click at x=1240, y=850&lt;/code&gt;) often fails due to display scaling differences and viewport misalignments.&lt;/p&gt;

&lt;p&gt;Browser-use implements &lt;strong&gt;Set-of-Mark (SoM)&lt;/strong&gt; visual grounding:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The injected JavaScript retrieves the bounding box for every interactive candidate.&lt;/li&gt;
&lt;li&gt;It paints an overlay of brightly colored bounding boxes containing &lt;strong&gt;numerical badges (&lt;code&gt;[1]&lt;/code&gt;, &lt;code&gt;[2]&lt;/code&gt;, &lt;code&gt;[15]&lt;/code&gt;)&lt;/strong&gt; directly onto the page.&lt;/li&gt;
&lt;li&gt;It takes a clean screenshot of this annotated state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Model's Action Space is Simplified&lt;/strong&gt;: The model does not calculate coordinates; it outputs high-level actions referencing IDs, such as &lt;code&gt;click_element(index=14)&lt;/code&gt; or &lt;code&gt;input_text(index=3, text="admin@company.com")&lt;/code&gt;. This increases action execution precision beyond 95%.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  II. Agent Cognitive Loop &amp;amp; State Machine Resilience
&lt;/h2&gt;

&lt;p&gt;Enterprise web automation rarely involves single-shot actions; it demands workflows spanning 10 to 30 sequential steps. Browser-use manages this via an &lt;strong&gt;Observe-Reason-Plan-Act-Verify (O-P-A-V)&lt;/strong&gt; state machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────┐
│                 Browser-use Cognitive Loop                  │
└─────────────────────────────────────────────────────────────┘
                             │
                             ▼
 1. Observe   ───► Prune DOM and capture SoM-annotated screenshot
                             │
                             ▼
 2. Reason    ───► Evaluate user goal vs. current interactive state
                             │
                             ▼
 3. Plan      ───► Select atomic action: Click / Type / Scroll / Tab
                             │
                             ▼
 4. Act       ───► Dispatch simulated input via Playwright CDP
                             │
                             ▼
 5. Verify    ───► Wait for network idle &amp;amp; DOM mutation; verify state
                             │
                             ├─► [Success] Proceed to next observation loop
                             └─► [Failure] Trigger self-healing retry or fallback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Dynamic Viewport Exploration and Scrolling
&lt;/h3&gt;

&lt;p&gt;When information resides below the fold or inside nested containers, the agent utilizes dedicated scroll primitives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;scroll_down(amount=500)&lt;/code&gt;: Scrolls the viewport and re-evaluates the fresh SoM layout.&lt;/li&gt;
&lt;li&gt;Maintains a lightweight historical trajectory of scrolled coordinates to avoid cycling endlessly between page extremes. For details on self-correction loops, see our guide on &lt;a href="https://blog.llmgo.top/en/articles/agent-reflection-self-correction/" rel="noopener noreferrer"&gt;Agent Reflection and Self-Correction&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. State Stagnation Detection &amp;amp; Self-Healing
&lt;/h3&gt;

&lt;p&gt;If an agent attempts three consecutive clicks on an element without altering DOM topology or visual layout, the built-in watchdog triggers recovery:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forces a clean page reload;&lt;/li&gt;
&lt;li&gt;Injects contextual feedback prompting the model: &lt;em&gt;"Previous click failed to trigger a state mutation. Inspect whether a blocking modal overlay exists or if scrolling is required."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  III. Production Hardening: Anti-Bot Evasion &amp;amp; Authentication
&lt;/h2&gt;

&lt;p&gt;Moving Browser-use into unattended 24/7 enterprise production environments requires handling real-world web defenses:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. WAF &amp;amp; Fingerprint Detection Evasion
&lt;/h3&gt;

&lt;p&gt;Standard Headless Chrome exposes obvious automation artifacts (&lt;code&gt;navigator.webdriver = true&lt;/code&gt;, missing WebGL vendor strings, static screen dimensions), leading to immediate blocks by Cloudflare or DataDome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Production Hardening Checklist&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy &lt;code&gt;playwright-stealth&lt;/code&gt; to scrub known automation properties;&lt;/li&gt;
&lt;li&gt;Randomize User-Agent headers, viewport dimensions, and hardware concurrency metrics;&lt;/li&gt;
&lt;li&gt;Add randomized micro-jitters to typing events and simulate human-like Bezier mouse curves.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. CAPTCHAs &amp;amp; Two-Factor Authentication (Human-in-the-Loop)
&lt;/h3&gt;

&lt;p&gt;Attempting to fully automate adversarial 3D rotation or visual puzzle CAPTCHAs in production introduces fragility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practice&lt;/strong&gt;: &lt;strong&gt;Human-in-the-Loop Handover&lt;/strong&gt;.&lt;br&gt;
When an agent detects a blocking challenge, it suspends its automated loop and issues a real-time notification (via Webhook, Slack, or Teams). A human operator opens a remote visual debug session via the Chrome DevTools Protocol (CDP), resolves the challenge within 30 seconds, and signals the agent to resume execution.&lt;/p&gt;




&lt;h2&gt;
  
  
  IV. Hands-on Implementation: Building an Autonomous Financial Research Agent
&lt;/h2&gt;

&lt;p&gt;Here is a complete, runnable script configuring Browser-use with multimodal models to execute a multi-step financial report download workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Environment Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;browser-use playwright langchain-openai
playwright &lt;span class="nb"&gt;install &lt;/span&gt;chromium
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Complete Python Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;browser_use&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Browser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BrowserConfig&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;browser_use.browser.context&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BrowserContextConfig&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Configure the multimodal vision backbone
# For production, utilize models with strong spatial grounding (GPT-4o, Claude 3.7 Sonnet, or Qwen2.5-VL)
&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&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;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_KEY&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="c1"&gt;# 2. Production browser resilience configuration
&lt;/span&gt;&lt;span class="n"&gt;browser_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BrowserConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;headless&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="c1"&gt;# Set to True for unattended production deployment
&lt;/span&gt;    &lt;span class="n"&gt;disable_security&lt;/span&gt;&lt;span class="o"&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;# Disregard self-signed intranet SSL certificates
&lt;/span&gt;    &lt;span class="n"&gt;extra_chromium_args&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;--disable-blink-features=AutomationControlled&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Scrub webdriver automation flag
&lt;/span&gt;        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--no-sandbox&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;--window-size=1920,1080&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="c1"&gt;# 3. Session isolation and recording configuration
&lt;/span&gt;&lt;span class="n"&gt;context_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BrowserContextConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;viewport&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;width&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1920&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;height&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1080&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;save_recording_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./recordings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Record video artifacts for auditing and triage
&lt;/span&gt;    &lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en-US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_enterprise_workflow&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Browser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;browser_config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;context_config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 4. Define high-level business objective
&lt;/span&gt;    &lt;span class="n"&gt;task_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    1. Navigate to https://example-finance-portal.com/login
    2. If a login form is displayed, enter &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;finance_bot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; as username, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Secr3t_Pass!&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; as password, and click Submit
    3. Once logged in, locate and click &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Financial Reconciliation&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; in the sidebar
    4. Set the date range filter to &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2026 Q2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, then click &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Export Summary CSV&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;
    5. Wait for the download to complete and confirm that a success modal appears
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="c1"&gt;# 5. Initialize the Browser-use Agent
&lt;/span&gt;    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;task_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;browser_context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;use_vision&lt;/span&gt;&lt;span class="o"&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;# Enable Set-of-Mark visual grounding
&lt;/span&gt;        &lt;span class="n"&gt;max_failures&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                 &lt;span class="c1"&gt;# Maximum retry attempts per step
&lt;/span&gt;        &lt;span class="n"&gt;max_actions_per_step&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;          &lt;span class="c1"&gt;# Allow compound actions per turn to reduce latency
&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;🚀 Launching enterprise autonomous Browser-use agent...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_steps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;25&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;✅ Execution Summary:&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;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;final_result&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&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;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;run_enterprise_workflow&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;By eliminating hardcoded selectors, the agent remains functional even when frontend teams update layout classes. For debugging and session logging, review our &lt;a href="https://blog.llmgo.top/en/articles/agent-observability-debugging/" rel="noopener noreferrer"&gt;Agent Observability and Debugging Guide&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  V. Enterprise Architecture &amp;amp; Cost Trade-offs
&lt;/h2&gt;

&lt;p&gt;Autonomous web agents do not completely supplant direct API calls. Production systems should adopt a &lt;strong&gt;layered automation hierarchy&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;Automation Layer&lt;/th&gt;
&lt;th&gt;Ideal Workload&lt;/th&gt;
&lt;th&gt;Execution Latency&lt;/th&gt;
&lt;th&gt;Cost per Step&lt;/th&gt;
&lt;th&gt;Reliability&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Direct REST/GraphQL APIs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Standardized, documented internal endpoints&lt;/td&gt;
&lt;td&gt;Sub-100ms&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;High (Schema Contract)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deterministic Playwright Scripts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High-volume, static regression smoke tests&lt;/td&gt;
&lt;td&gt;Sub-second&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;Medium (Breaks on UI updates)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Browser-use Vision Agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Legacy systems without APIs, anti-bot sites, exploratory workflows&lt;/td&gt;
&lt;td&gt;~3s per step&lt;/td&gt;
&lt;td&gt;$0.01 - $0.05 per step (Token-based)&lt;/td&gt;
&lt;td&gt;High (Adaptive self-healing)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Frequently Asked Questions (FAQ)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Q1: Does capturing screenshots on every step cause token costs to explode?
&lt;/h3&gt;

&lt;p&gt;No. Browser-use automatically compresses and resizes screenshots (typically capping resolution at 1280px width), keeping per-image consumption within a few hundred tokens. Combined with distilled DOM pruning, the average per-step cost remains between &lt;strong&gt;800 and 2,500 tokens&lt;/strong&gt;. For high-volume private workflows, hosting open-weight models (such as Qwen2.5-VL-72B via &lt;a href="https://blog.llmgo.top/en/articles/vllm-serving-guide/" rel="noopener noreferrer"&gt;vLLM Serving&lt;/a&gt;) reduces per-token marginal costs to near zero.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2: How does the agent track state across multi-tab popups?
&lt;/h3&gt;

&lt;p&gt;Browser-use maintains an integrated tab manager. When a click triggers &lt;code&gt;window.open&lt;/code&gt; or a popup, Playwright catches the &lt;code&gt;context.on('page')&lt;/code&gt; event and injects the active tab list (&lt;code&gt;available_tabs: [Tab 0: Home, Tab 1: Checkout]&lt;/code&gt;) into the prompt state. The model issues &lt;code&gt;switch_tab(tab_id=1)&lt;/code&gt; commands while maintaining unified execution history in the primary controller.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3: Can Browser-use run in headless containerized cloud environments?
&lt;/h3&gt;

&lt;p&gt;Yes. In production Kubernetes clusters, the standard deployment pattern packages the agent inside a lightweight Linux container utilizing &lt;strong&gt;Xvfb (X Virtual Framebuffer)&lt;/strong&gt; to emulate a display. This enables headless execution while preserving full screenshot and Set-of-Mark visual grounding capabilities.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://blog.llmgo.top/en/articles/browser-use-agent-architecture/" rel="noopener noreferrer"&gt;Nobita Talks AI&lt;/a&gt; on blog.llmgo.top.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>autonomousagents</category>
      <category>agents</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>vLLM Online Inference in Production: From Architecture to Token Billing</title>
      <dc:creator>ifnodoraemon</dc:creator>
      <pubDate>Sun, 20 Sep 2026 05:04:59 +0000</pubDate>
      <link>https://dev.to/ifnodoraemon/vllm-online-inference-in-production-from-architecture-to-token-billing-1c93</link>
      <guid>https://dev.to/ifnodoraemon/vllm-online-inference-in-production-from-architecture-to-token-billing-1c93</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: Why vLLM?
&lt;/h2&gt;

&lt;p&gt;In 2026, if you need to deploy an LLM inference service in production — whether it's an internal AI assistant or a commercial API platform — you'll almost certainly encounter &lt;strong&gt;vLLM&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Born in UC Berkeley's Sky Computing Lab and published at SOSP 2023, vLLM has become one of the most active open-source inference engines with 2,000+ contributors. Its motto is straightforward: &lt;strong&gt;"Easy, fast, and cheap LLM serving for everyone."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But what exactly makes vLLM fast? How do you monitor and optimize cache hit rates? What should &lt;code&gt;--max-num-seqs&lt;/code&gt; be set to? Why is token billing such a deep trap in self-hosted inference? This article covers &lt;strong&gt;architecture, caching mechanisms, scheduling algorithms, deployment, performance tuning, and token billing&lt;/strong&gt; — everything you need for production-ready vLLM.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 1: Understanding vLLM's Core Engine in 5 Minutes
&lt;/h2&gt;

&lt;p&gt;LLM inference fundamentally splits into two distinct phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prefill&lt;/strong&gt;: Process the entire user input at once, computing attention for all tokens. This is &lt;strong&gt;compute-bound&lt;/strong&gt; — GPU cores are maxing out on matrix multiplications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decode&lt;/strong&gt;: Generate output tokens one by one, each depending on the KV Cache of all preceding tokens. This is &lt;strong&gt;memory-bandwidth-bound&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding this fundamental difference is the key to understanding every vLLM optimization.&lt;/p&gt;

&lt;p&gt;Traditional frameworks have two fatal problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Memory waste&lt;/strong&gt;: Each request's KV Cache requires pre-allocated contiguous GPU memory, even if only 10% is used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Poor concurrency&lt;/strong&gt;: Static batching waits for the slowest request to finish before processing the next batch.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. PagedAttention: Virtual Memory for GPU
&lt;/h3&gt;

&lt;p&gt;vLLM's most groundbreaking innovation, borrowing the &lt;strong&gt;virtual memory paging&lt;/strong&gt; concept from operating systems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traditional: Pre-allocate contiguous memory per request (like MS-DOS real mode)
  Request A: [████████████░░░░░░░░] ← 60% wasted
  Request B: [██████░░░░░░░░░░░░░░] ← 70% wasted
  Request C: "Sorry, out of memory. Please queue."

PagedAttention: Slice memory into fixed-size pages (Blocks), allocate on demand
  Physical blocks:     [P1][P2][P3][P4][P5][P6][P7][P8]
  Request A page table: P1 → P3 → P5 (use only what you need, non-contiguous OK)
  Request B page table: P2 → P4
  Request C page table: P6 → P7 (previously couldn't fit, now easily admitted)
  Free pool:           P8 (ready for new requests or existing request growth)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key insight&lt;/strong&gt;: Pages don't need to be physically contiguous. vLLM maintains a &lt;strong&gt;Block Table&lt;/strong&gt; for mapping, achieving three breakthroughs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Near-zero waste&lt;/strong&gt;: KV Cache memory waste drops from &lt;strong&gt;60-80%&lt;/strong&gt; to &lt;strong&gt;&amp;lt;4%&lt;/strong&gt; (only the last block's internal fragmentation).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2-4x concurrency&lt;/strong&gt;: Same GPU handles 2-4x more concurrent requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared reuse&lt;/strong&gt;: Requests sharing the same prefix (e.g., system prompt) can point to the &lt;strong&gt;same physical pages&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Continuous Batching
&lt;/h3&gt;

&lt;p&gt;Traditional inference is like a restaurant requiring all guests to arrive, order, and leave simultaneously. vLLM introduces &lt;strong&gt;iteration-level scheduling&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;Timeline:
  t=0  [Req A-decode] [Req B-decode] [Req C-prefill] [          ]
  t=1  [Req A-decode] [Req B-done✓]  [Req C-decode]  [Req D-new!]
  t=2  [Req A-decode] [Req D-prefill] [Req C-decode]  [          ]
  t=3  [Req A-done✓]  [Req D-decode]  [Req C-done✓]  [Req E-new!]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Request finishes → &lt;strong&gt;immediately&lt;/strong&gt; removed. New request arrives → &lt;strong&gt;immediately&lt;/strong&gt; inserted. GPU stays &lt;strong&gt;fully utilized&lt;/strong&gt; at all times.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Chunked Prefill — The Latency Lifesaver for Online Serving
&lt;/h3&gt;

&lt;p&gt;A hidden danger in continuous batching: a &lt;strong&gt;10,000-token document&lt;/strong&gt; will monopolize the GPU for hundreds of milliseconds during prefill, stalling all other decoding requests.&lt;/p&gt;

&lt;p&gt;Chunked prefill divides long prompts into smaller chunks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scheduler maintains a "token budget" per iteration (e.g., max_num_batched_tokens = 8192)

Round 1: [Req A prefix tokens 0-2047]  + [Req B decode 1 token] + [Req C decode 1 token]
Round 2: [Req A prefix tokens 2048-4095] + [Req B decode 1 token] + [Req C decode 1 token]
...
Round 5: [Req A remaining prefix tokens] + [Req B decode 1 token] + [Req C decode 1 token]
Round 6: [Req A starts decoding!] + [Req B decode 1 token] + [Req C decode 1 token]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Core scheduling policy&lt;/strong&gt;: vLLM V1 engine (v0.29.0) prioritizes &lt;strong&gt;active decode requests&lt;/strong&gt; first, then uses remaining budget for new prefill chunks. Users B and C barely notice User A's massive input.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Must-enable for online services&lt;/strong&gt;: &lt;code&gt;--enable-chunked-prefill&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Layer 2 Deep Dive: APC Prefix Caching — Understanding It Pays Off
&lt;/h2&gt;

&lt;p&gt;If PagedAttention solves "how to allocate memory," &lt;strong&gt;Automatic Prefix Caching (APC)&lt;/strong&gt; solves "how to reuse what's already been computed."&lt;/p&gt;

&lt;h3&gt;
  
  
  Why APC Is Critical for Online Services
&lt;/h3&gt;

&lt;p&gt;Real-world online inference requests typically look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Req 1: [System Prompt (800T) | Multi-turn History (2000T) | New Message (50T)]
Req 2: [System Prompt (800T) | Multi-turn History (2000T) | New Message (30T)]
Req 3: [System Prompt (800T) | Different User Chat (500T) | New Message (80T)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Requests 1 and 2 share &lt;strong&gt;2,800 tokens&lt;/strong&gt; of prefix! Request 3 shares &lt;strong&gt;800 tokens&lt;/strong&gt; of system prompt. Recomputing from scratch every time is enormously wasteful.&lt;/p&gt;

&lt;h3&gt;
  
  
  How APC Works: Block Hashing + Global Hash Table + LRU Eviction
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Block Hashing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;vLLM partitions all token sequences into fixed-size blocks (default: 16 tokens). Each block is uniquely identified by a &lt;strong&gt;chained hash&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;Hash calculation: hash(parent_block_hash + current_block_tokens)

Example: System prompt "You are a helpful AI assistant..." (800 tokens)
  Block_0: hash(NULL + tokens[0:16])       = 0xA1B2C3...
  Block_1: hash(0xA1B2C3 + tokens[16:32])  = 0xD4E5F6...
  Block_2: hash(0xD4E5F6 + tokens[32:48])  = 0x789ABC...
  ...     (50 blocks total)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why chained hashing?&lt;/strong&gt; The same 16 tokens at different context positions produce entirely different attention outputs. Chain hashing ensures only &lt;strong&gt;identical prefixes&lt;/strong&gt; match.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Global Hash Table Lookup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;vLLM maintains a global &lt;code&gt;HashMap&amp;lt;BlockHash, PhysicalBlock&amp;gt;&lt;/code&gt;. When a new request arrives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New request: [System Prompt | User Chat | New Message]
1. Scheduler computes hash for each block
2. Queries global hash table one by one:
   Block_0 (0xA1B2C3) → HIT! Reference physical Block #42
   Block_1 (0xD4E5F6) → HIT! Reference physical Block #43
   ... (49 more hits)
   Block_50 (0xNEW001) → MISS. New message content, needs computation
3. Result: 50 blocks reused, only compute from Block_50 onwards
   → Prefill computation reduced by 98%!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: LRU Eviction Policy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GPU memory is finite. vLLM uses &lt;strong&gt;reference counting + LRU&lt;/strong&gt; to manage the cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Each physical block has two key attributes:
  - ref_count: how many active requests reference this block
  - last_access_time: timestamp of last access

Eviction rules:
  1. Blocks with ref_count &amp;gt; 0 are NEVER evicted (actively in use!)
  2. Blocks with ref_count = 0 enter the "candidate pool"
  3. When memory runs low, evict the block with the oldest last_access_time
  4. Remove its hash from the global table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Four Key APC Use Cases
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Reusable Prefix&lt;/th&gt;
&lt;th&gt;Performance Gain&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-turn chat&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;System prompt + chat history&lt;/td&gt;
&lt;td&gt;Later turns approach zero prefill time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Document QA (RAG)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Thousands of document tokens&lt;/td&gt;
&lt;td&gt;Multiple queries on same doc = nearly free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code completion&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Existing file content&lt;/td&gt;
&lt;td&gt;Incremental computation per keystroke&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Template batch processing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Identical instruction prefix&lt;/td&gt;
&lt;td&gt;1000 same-template requests compute prefix once&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  APC Limitations
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Output &amp;gt;&amp;gt; Input&lt;/strong&gt;: Prefill is a small fraction of total latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every request is unique&lt;/strong&gt;: No shared prefixes, no cache hits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minor miss overhead&lt;/strong&gt;: Hash computation costs CPU time (usually negligible)&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key config&lt;/strong&gt;: &lt;code&gt;--enable-prefix-caching&lt;/code&gt; (default in vLLM V1 engine / v0.29.0).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Getting Cache Hit Data in API Responses
&lt;/h3&gt;

&lt;p&gt;vLLM can &lt;strong&gt;tell you exactly how many tokens hit the cache&lt;/strong&gt; in each response. Just add one startup parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vllm serve Qwen/Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-prefix-caching&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-prompt-tokens-details&lt;/span&gt;    &lt;span class="c"&gt;# ← Key! Adds cached_tokens to usage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;usage&lt;/code&gt; field will now include &lt;code&gt;prompt_tokens_details&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"usage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"completion_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;423&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"total_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3423&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt_tokens_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cached_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2800&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this means&lt;/strong&gt;: Of 3000 prompt tokens, 2800 were reused from cache, only 200 needed GPU compute. &lt;strong&gt;Your cost is 6.7% of list price, but you bill the user for all 3000 tokens.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Critical for billing&lt;/strong&gt;: Your middleware should record both &lt;code&gt;prompt_tokens&lt;/code&gt; (user billing basis) and &lt;code&gt;cached_tokens&lt;/code&gt; (your actual cost basis). The gap is your profit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Cache Hit Rate Monitoring: Prometheus Metrics
&lt;/h3&gt;

&lt;p&gt;vLLM V1 engine (v0.29.0) uses Counter-based metrics (replacing the deprecated &lt;code&gt;gpu_prefix_cache_hit_rate&lt;/code&gt; Gauge):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# V1 prefix cache metrics (Counter type, precise and reliable)
vllm_prefix_cache_hits              # Cache hit tokens total (Counter)
vllm_prefix_cache_queries           # Cache query tokens total (Counter)

# PromQL for real-time hit rate (use this in Grafana)
(rate(vllm_prefix_cache_hits[5m]) / rate(vllm_prefix_cache_queries[5m])) * 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Healthy cache hit rate benchmarks&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;Scenario&lt;/th&gt;
&lt;th&gt;Expected Hit Rate&lt;/th&gt;
&lt;th&gt;If Lower, Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Multi-turn chat (same session)&lt;/td&gt;
&lt;td&gt;80%-95%&lt;/td&gt;
&lt;td&gt;Dynamic content inserted in prefix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAG document QA&lt;/td&gt;
&lt;td&gt;60%-85%&lt;/td&gt;
&lt;td&gt;Document diversity too high, or cache pool too small&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Template batch processing&lt;/td&gt;
&lt;td&gt;90%+&lt;/td&gt;
&lt;td&gt;Template not at the front of prompt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Completely random requests&lt;/td&gt;
&lt;td&gt;&amp;lt;10%&lt;/td&gt;
&lt;td&gt;Normal — APC doesn’t help here&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Best Practices for Maximizing Cache Hits
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Static content first&lt;/strong&gt;: Place system instructions and documents at the beginning of prompts, dynamic content (user messages) after.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid dynamic elements in prefixes&lt;/strong&gt;: e.g., &lt;code&gt;"Current time is 2026-04-14 10:00"&lt;/code&gt; — a time change invalidates the entire cache chain. Put timestamps at the end.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increase &lt;code&gt;--gpu-memory-utilization&lt;/code&gt;&lt;/strong&gt;: More VRAM = larger cache pool = lower LRU eviction rate = higher hit rates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintain session continuity&lt;/strong&gt;: Let vLLM naturally accumulate cache across turns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor &lt;code&gt;cached_tokens&lt;/code&gt; / &lt;code&gt;prompt_tokens&lt;/code&gt; ratio&lt;/strong&gt;: This is your "profit margin". Analyze by user/scenario to identify low-hit-rate patterns.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Layer 3: OpenAI-Compatible API &amp;amp; Advanced Capabilities
&lt;/h2&gt;

&lt;p&gt;vLLM natively provides an OpenAI-compatible API — your application code stays the same, just change the &lt;code&gt;base_url&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Start
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;vllm

vllm serve Qwen/Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dtype&lt;/span&gt; auto &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--api-key&lt;/span&gt; your-secret-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--port&lt;/span&gt; 8000 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-prefix-caching&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Supported Endpoints
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chat Completions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/v1/chat/completions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Conversational AI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Completions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/v1/completions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Text completion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Responses&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/v1/responses&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI Responses API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Embeddings&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/v1/embeddings&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Vector embeddings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Models&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/v1/models&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tokenizer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/tokenize&lt;/code&gt; / &lt;code&gt;/detokenize&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Token encode/decode (billing helper)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transcriptions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/v1/audio/transcriptions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Speech-to-text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Realtime&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/v1/realtime&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Real-time voice (WebSocket)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Structured Output &amp;amp; Guided Decoding
&lt;/h3&gt;

&lt;p&gt;Online services often require &lt;strong&gt;strictly formatted JSON&lt;/strong&gt; output. vLLM has built-in &lt;strong&gt;Guided Decoding&lt;/strong&gt; support:&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="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;Qwen/Qwen2.5-72B-Instruct&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Extract names and locations&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="n"&gt;extra_body&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;guided_json&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;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;object&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;properties&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;names&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;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;array&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;items&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;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;string&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;locations&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;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;array&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;items&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;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;string&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;required&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;names&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;locations&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="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;Four constraint formats: &lt;code&gt;guided_json&lt;/code&gt;, &lt;code&gt;guided_regex&lt;/code&gt;, &lt;code&gt;guided_choice&lt;/code&gt;, &lt;code&gt;guided_grammar&lt;/code&gt;. Powered by &lt;strong&gt;XGrammar&lt;/strong&gt; (pushdown automata-based), with &lt;strong&gt;&amp;lt;5% latency impact&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-LoRA Serving
&lt;/h3&gt;

&lt;p&gt;Serve multiple fine-tuned adapters on a single base model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vllm serve Qwen/Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-lora&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-loras&lt;/span&gt; 8 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lora-modules&lt;/span&gt; customer-a&lt;span class="o"&gt;=&lt;/span&gt;/path/to/lora-a customer-b&lt;span class="o"&gt;=&lt;/span&gt;/path/to/lora-b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uses &lt;strong&gt;batched GEMM&lt;/strong&gt; to dynamically group sequences using different adapters. Each LoRA adapter is typically only tens of MB vs. hundreds of GB for the base model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Production Deployment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; vllm-server &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--gpus&lt;/span&gt; all &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--ipc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 8000:8000 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; /path/to/models:/models &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;VLLM_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-secret-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;PROMETHEUS_MULTIPROC_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/prometheus &lt;span class="se"&gt;\&lt;/span&gt;
  vllm/vllm-openai:v0.29.0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--model&lt;/span&gt; /models/Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dtype&lt;/span&gt; auto &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--gpu-memory-utilization&lt;/span&gt; 0.90 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-model-len&lt;/span&gt; 8192 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-prefix-caching&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-chunked-prefill&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-prompt-tokens-details&lt;/span&gt;    &lt;span class="c"&gt;# Expose cached_tokens for billing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Always use &lt;code&gt;--ipc=host&lt;/code&gt;&lt;/strong&gt;: vLLM uses PyTorch shared memory for multi-process communication. Without this flag, you'll get errors inside containers. This is the #1 beginner mistake.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Layer 4: Performance Tuning
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Core Metrics for Online Services
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Full Name&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Goal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TTFT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Time to First Token&lt;/td&gt;
&lt;td&gt;Time from request to first token&lt;/td&gt;
&lt;td&gt;Lower → "responsive"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ITL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Inter-Token Latency&lt;/td&gt;
&lt;td&gt;Gap between consecutive tokens&lt;/td&gt;
&lt;td&gt;Lower → "smooth typing"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Throughput&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;tokens/s&lt;/td&gt;
&lt;td&gt;Total tokens processed per second&lt;/td&gt;
&lt;td&gt;Higher → lower cost per token&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Core tension&lt;/strong&gt;: Higher throughput and lower latency are naturally opposed. Online services must find the sweet spot.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complete Tuning Guide
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vllm serve Qwen/Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--gpu-memory-utilization&lt;/span&gt; 0.90 &lt;span class="se"&gt;\ &lt;/span&gt;    &lt;span class="c"&gt;# [1]&lt;/span&gt;
  &lt;span class="nt"&gt;--max-model-len&lt;/span&gt; 8192 &lt;span class="se"&gt;\ &lt;/span&gt;             &lt;span class="c"&gt;# [2] THE MOST CRITICAL PARAMETER&lt;/span&gt;
  &lt;span class="nt"&gt;--max-num-seqs&lt;/span&gt; 256 &lt;span class="se"&gt;\ &lt;/span&gt;               &lt;span class="c"&gt;# [3]&lt;/span&gt;
  &lt;span class="nt"&gt;--max-num-batched-tokens&lt;/span&gt; 16384 &lt;span class="se"&gt;\ &lt;/span&gt;   &lt;span class="c"&gt;# [4]&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-chunked-prefill&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;         &lt;span class="c"&gt;# [5]&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-prefix-caching&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;          &lt;span class="c"&gt;# [6]&lt;/span&gt;
  &lt;span class="nt"&gt;--quantization&lt;/span&gt; fp8 &lt;span class="se"&gt;\ &lt;/span&gt;               &lt;span class="c"&gt;# [7]&lt;/span&gt;
  &lt;span class="nt"&gt;--kv-cache-dtype&lt;/span&gt; fp8_e5m2 &lt;span class="se"&gt;\ &lt;/span&gt;        &lt;span class="c"&gt;# [8]&lt;/span&gt;
  &lt;span class="nt"&gt;--tensor-parallel-size&lt;/span&gt; 2 &lt;span class="se"&gt;\ &lt;/span&gt;         &lt;span class="c"&gt;# [9]&lt;/span&gt;
  &lt;span class="nt"&gt;--num-speculative-tokens&lt;/span&gt; 5 &lt;span class="se"&gt;\ &lt;/span&gt;       &lt;span class="c"&gt;# [10]&lt;/span&gt;
  &lt;span class="nt"&gt;--speculative-model&lt;/span&gt; Qwen/Qwen2.5-1.5B-Instruct
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  [1] &lt;code&gt;--gpu-memory-utilization&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.70: 30% wasted → tiny APC cache pool → hit rate plummets
0.98: almost no buffer → OOM crash during spikes → all in-flight requests lost
0.90~0.95: sweet spot for production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  [2] &lt;code&gt;--max-model-len&lt;/code&gt; — THE #1 PERFORMANCE KILLER
&lt;/h4&gt;

&lt;p&gt;vLLM pre-calculates KV Cache space based on this value. Many beginners use the model default (e.g., Qwen2.5's 131,072).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Default 131072 → KV Cache reserves 30x more space → concurrency drops from 50 to 2
Set to actual need 8192 → KV Cache right-sized → concurrency restored

This single parameter change can be more impactful than all other optimizations combined.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  [3-4] Concurrency &amp;amp; Token Budget
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Online chat&lt;/strong&gt; (latency-first): &lt;code&gt;max-num-seqs 64-256&lt;/code&gt;, &lt;code&gt;max-num-batched-tokens 8192-16384&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch processing&lt;/strong&gt; (throughput-first): &lt;code&gt;max-num-seqs 2048-4096&lt;/code&gt;, &lt;code&gt;max-num-batched-tokens 32768&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  [7-8] Quantization
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GPU&lt;/th&gt;
&lt;th&gt;Recommended&lt;/th&gt;
&lt;th&gt;Accuracy Loss&lt;/th&gt;
&lt;th&gt;Effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;H100/H800&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;FP8 (&lt;code&gt;--quantization fp8&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&amp;lt;1%&lt;/td&gt;
&lt;td&gt;~1.5x throughput, zero-calibration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A100/L40S&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;INT8 GPTQ/AWQ&lt;/td&gt;
&lt;td&gt;≈0%&lt;/td&gt;
&lt;td&gt;2x memory reduction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Blackwell B200&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NVFP4&lt;/td&gt;
&lt;td&gt;≤1%&lt;/td&gt;
&lt;td&gt;2x throughput vs FP8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;KV Cache Quantization&lt;/strong&gt; (&lt;code&gt;--kv-cache-dtype fp8_e5m2&lt;/code&gt;): Halves KV Cache memory with minimal quality impact, especially impactful for long-context (8K-128K) scenarios.&lt;/p&gt;

&lt;h4&gt;
  
  
  [9] Tensor Parallelism
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Common mistake: 8 GPUs → TP=8 → worse throughput than TP=4

Reason: AllReduce communication overhead can eat 40% of added compute

Correct strategy:
  1. Use minimum TP to fit the model (70B FP8 on 2x H100 → TP=2)
  2. Use extra GPUs for more replicas + load balancer
  Result: 2 instances × TP=2 often 30-50% higher throughput than 1 instance × TP=4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Advanced&lt;/strong&gt;: Check GPU topology with &lt;code&gt;nvidia-smi topo -m&lt;/code&gt;. TP GPUs should be NVLink-connected, not PCIe-bridged (5-10x latency difference).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  [10] Speculative Decoding
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Low concurrency (&amp;lt;10 QPS): 2-5x latency improvement
High concurrency (&amp;gt;100 QPS): diminishing returns (GPU already saturated)

Best for: real-time chat, internal tools, latency-sensitive Agent calls
Not for: high-concurrency API services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Layer 5: Disaggregated Serving — Architecture for Scale
&lt;/h2&gt;

&lt;p&gt;At &lt;strong&gt;hundreds to thousands of QPS&lt;/strong&gt;, Prefill and Decode interfere with each other:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    ┌──────────────────┐
                    │   Request Router  │
                    └──────┬───────────┘
              ┌────────────┼────────────┐
              ▼                         ▼
    ┌──────────────────┐     ┌──────────────────┐
    │  Prefill Cluster  │     │  Decode Cluster   │
    │  (Compute GPUs)   │     │  (Bandwidth GPUs) │
    │  H100 SXM / B200  │     │  L40S / A100      │
    └────────┬─────────┘     └────────▲─────────┘
             └────── KV Cache Transfer ───┘
                   (NIXL / RDMA)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Core advantages&lt;/strong&gt;: Independent scaling, hardware heterogeneity (cost savings), eliminated cross-phase interference.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 6: Token Billing — The Business Lifeline
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Usage Data
&lt;/h3&gt;

&lt;p&gt;vLLM returns &lt;code&gt;usage&lt;/code&gt; in every response. With &lt;code&gt;--enable-prompt-tokens-details&lt;/code&gt;, it also includes cache hit details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"usage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"completion_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;423&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"total_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3423&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt_tokens_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cached_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2800&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Billing Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → [API Gateway (auth/rate-limit)] → [vLLM Engine]
                  ↓                              ↓
         [Billing Middleware] ←──── Extract usage from response
                  ↓
         Billing DB (user_id, org_id, prompt_tokens, completion_tokens, timestamp)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Prometheus Metrics
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Token metering
vllm_prompt_tokens_total / vllm_generation_tokens_total

# Cache efficiency (V1, replaces deprecated gpu_prefix_cache_hit_rate)
vllm_prefix_cache_hits / vllm_prefix_cache_queries
# PromQL: (rate(vllm_prefix_cache_hits[5m]) / rate(vllm_prefix_cache_queries[5m])) * 100

# Latency
vllm_time_to_first_token_seconds / vllm_inter_token_latency_seconds

# Saturation
vllm_gpu_cache_usage_perc / vllm_num_requests_waiting / vllm_num_preemptions_total
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Must set&lt;/strong&gt; &lt;code&gt;PROMETHEUS_MULTIPROC_DIR&lt;/code&gt; env var for correct multi-process metric collection.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Five Token Billing Pitfalls
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pitfall 1: Should cached prefix tokens be billed?&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;Your actual compute cost:
  Total prompt = 3000 tokens
  APC prefix hit = 2800 tokens (cost ≈ 0)
  Actually computed = 200 tokens

User pays: Full 3000 prompt_tokens (industry convention)
Your profit = User payment for 3000 tokens - Your GPU cost for 200 tokens
Prefix caching is your profit engine.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pitfall 2: Streaming usage only in last chunk.&lt;/strong&gt; Extract &lt;code&gt;usage&lt;/code&gt; from the chunk where &lt;code&gt;finish_reason != null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pitfall 3: Speculative decoding waste tokens.&lt;/strong&gt; vLLM's &lt;code&gt;completion_tokens&lt;/code&gt; automatically excludes rejected draft tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pitfall 4: &lt;code&gt;/tokenize&lt;/code&gt; endpoint mismatches.&lt;/strong&gt; Chat Template special tokens (&lt;code&gt;&amp;lt;|im_start|&amp;gt;&lt;/code&gt;) are included. Ensure your billing tokenizer matches vLLM's exactly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pitfall 5: Multimodal token counting.&lt;/strong&gt; Images encode as hundreds-to-thousands of visual tokens reflected in &lt;code&gt;prompt_tokens&lt;/code&gt;. Consider separate pricing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cost Analysis: Build vs Buy
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Qwen2.5-72B (FP8) on 2x H100:
  GPU cost: ~$7/hour = $168/day
  Throughput: ~4,000 tokens/s = ~345M tokens/day

vs. OpenAI GPT-4o ($2.50/M input + $10/M output):
  Same volume: ~$1,500/day

Self-hosted: $168/day vs API: $1,500/day → ~9x cheaper

Rule of thumb:
  &amp;lt; 10M tokens/day → Buy API (simpler)
  10M-100M tokens/day → Evaluate based on team capability
  &amp;gt; 100M tokens/day → Self-host (cost advantage is overwhelming)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Production Checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  I. GPU &amp;amp; Compute
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Recommended&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPU&lt;/td&gt;
&lt;td&gt;H100 SXM 80GB / A100 80GB&lt;/td&gt;
&lt;td&gt;H100 supports FP8 zero-calibration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interconnect&lt;/td&gt;
&lt;td&gt;NVLink 4.0 / NVSwitch&lt;/td&gt;
&lt;td&gt;TP GPUs must be NVLink (not PCIe)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CPU&lt;/td&gt;
&lt;td&gt;≥ (2 + N) physical cores (N=GPU count)&lt;/td&gt;
&lt;td&gt;Engine Core is CPU-sensitive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAM&lt;/td&gt;
&lt;td&gt;≥ model file size × 2&lt;/td&gt;
&lt;td&gt;For model loading&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  II. Storage &amp;amp; Model Loading
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Recommended&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model storage&lt;/td&gt;
&lt;td&gt;Local NVMe SSD / fast NFS&lt;/td&gt;
&lt;td&gt;Cold start from HuggingFace is too slow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;K8s&lt;/td&gt;
&lt;td&gt;PersistentVolume + InitContainer&lt;/td&gt;
&lt;td&gt;Pre-download via Job&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  III. Network &amp;amp; Security
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Recommended&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Multi-node&lt;/td&gt;
&lt;td&gt;InfiniBand RDMA / RoCE&lt;/td&gt;
&lt;td&gt;Required for disaggregated inference&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;External&lt;/td&gt;
&lt;td&gt;Reverse proxy (Nginx/Kong)&lt;/td&gt;
&lt;td&gt;vLLM’s &lt;code&gt;--api-key&lt;/code&gt; isn’t production security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Isolation&lt;/td&gt;
&lt;td&gt;Private VPC&lt;/td&gt;
&lt;td&gt;vLLM inter-node comms are unencrypted by default&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  IV. vLLM Engine Params
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vllm serve /models/Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--gpu-memory-utilization&lt;/span&gt; 0.90 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-model-len&lt;/span&gt; 8192 &lt;span class="se"&gt;\ &lt;/span&gt;                   &lt;span class="c"&gt;# ⚠️ MOST CRITICAL&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-chunked-prefill&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-prefix-caching&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-prompt-tokens-details&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;         &lt;span class="c"&gt;# Expose cached_tokens&lt;/span&gt;
  &lt;span class="nt"&gt;--max-num-seqs&lt;/span&gt; 256 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--quantization&lt;/span&gt; fp8 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--kv-cache-dtype&lt;/span&gt; fp8_e5m2 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tensor-parallel-size&lt;/span&gt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  V. Monitoring
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Recommended&lt;/th&gt;
&lt;th&gt;Key Panels&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Metrics&lt;/td&gt;
&lt;td&gt;Prometheus&lt;/td&gt;
&lt;td&gt;Cache hit rate, KV Cache %, queue depth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dashboards&lt;/td&gt;
&lt;td&gt;Grafana&lt;/td&gt;
&lt;td&gt;6 panels: cache hits, throughput, latency, queue, preemptions, TTFT P99&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logging&lt;/td&gt;
&lt;td&gt;ELK / Loki&lt;/td&gt;
&lt;td&gt;Request-level traces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tracing&lt;/td&gt;
&lt;td&gt;OpenTelemetry&lt;/td&gt;
&lt;td&gt;End-to-end latency&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  VI. Billing &amp;amp; Business
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Recommended&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gateway&lt;/td&gt;
&lt;td&gt;Kong / Nginx / Traefik&lt;/td&gt;
&lt;td&gt;Auth, rate limiting, routing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Billing middleware&lt;/td&gt;
&lt;td&gt;Custom Python/Go&lt;/td&gt;
&lt;td&gt;Extract &lt;code&gt;usage&lt;/code&gt; + &lt;code&gt;cached_tokens&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;TimescaleDB / ClickHouse&lt;/td&gt;
&lt;td&gt;Time-series billing records&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  VII. High Availability
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Recommended&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Load balancer&lt;/td&gt;
&lt;td&gt;Nginx / Traefik / K8s Service&lt;/td&gt;
&lt;td&gt;Multi-replica traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Health checks&lt;/td&gt;
&lt;td&gt;Active inference probes&lt;/td&gt;
&lt;td&gt;Don’t just check process liveness&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Orchestration&lt;/td&gt;
&lt;td&gt;Kubernetes + KEDA&lt;/td&gt;
&lt;td&gt;Autoscale on queue depth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rolling updates&lt;/td&gt;
&lt;td&gt;Start new before stopping old&lt;/td&gt;
&lt;td&gt;Model loading takes 30s+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Key action items:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Get running first, tune later&lt;/strong&gt;: Start with a simple &lt;code&gt;vllm serve&lt;/code&gt;, validate business logic, then optimize.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;max-model-len&lt;/code&gt; is priority #1&lt;/strong&gt;: This single parameter may outweigh all other optimizations combined.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor first&lt;/strong&gt;: Set up Prometheus + Grafana. &lt;code&gt;gpu_cache_usage_perc&lt;/code&gt; is the single most important metric.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache hit rate = profit margin&lt;/strong&gt;: Track APC hits, optimize prompt structure to front-load static content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bill at the gateway&lt;/strong&gt;: Don't modify vLLM source code. Intercept &lt;code&gt;usage&lt;/code&gt; at the gateway layer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Stay updated via &lt;a href="https://docs.vllm.ai/" rel="noopener noreferrer"&gt;official docs&lt;/a&gt; and &lt;a href="https://github.com/vllm-project/vllm/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Frequently Asked Questions (FAQ)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Q1: How to troubleshoot CUDA out of memory (OOM) when launching vLLM?
&lt;/h3&gt;

&lt;p&gt;First inspect &lt;code&gt;--gpu-memory-utilization&lt;/code&gt; (default 0.90 allocates 90% of GPU VRAM for weights and KV Cache); adjust it to 0.85 if other background processes consume VRAM. Most importantly, explicitly configure &lt;code&gt;--max-model-len&lt;/code&gt; (e.g. 4096 or 8192) according to your practical workload instead of letting it allocate for the theoretical context window. If VRAM remains constrained, enable 4-bit/8-bit weight quantization by consulting our &lt;a href="https://blog.llmgo.top/en/articles/quantization-hands-on-guide/" rel="noopener noreferrer"&gt;Quantization Hands-on Guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2: When should I choose Tensor Parallelism vs Pipeline Parallelism?
&lt;/h3&gt;

&lt;p&gt;On a single machine with multiple GPUs connected via NVLink (such as 4x or 8x A100/H100), Tensor Parallelism (&lt;code&gt;--tensor-parallel-size&lt;/code&gt;) is preferred because NVLink communication latency is negligible. For multi-node distributed setups, the best practice is multi-instance Data Parallelism with a lightweight load balancer, which prevents inter-node network synchronization bottlenecks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3: What makes vLLM superior to Ollama or TGI for production serving?
&lt;/h3&gt;

&lt;p&gt;vLLM is specifically engineered for high-concurrency enterprise throughput. Utilizing PagedAttention, Continuous Batching, and Chunked Prefill with Automatic Prefix Caching (APC), vLLM achieves 3x to 5x higher sustained throughput under variable batch requests while exposing a native OpenAI-compatible API. For hardware background, refer to our &lt;a href="https://blog.llmgo.top/en/articles/nvidia-gpu-package-architecture/" rel="noopener noreferrer"&gt;NVIDIA GPU Package Architecture&lt;/a&gt; breakdown.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://blog.llmgo.top/en/articles/vllm-serving-guide/" rel="noopener noreferrer"&gt;Nobita Talks AI&lt;/a&gt; on blog.llmgo.top.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>inferencedeployment</category>
      <category>machinelearning</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Speculative Decoding in Production: From Draft Models to EAGLE-3 Dynamic Trees for 3x-5x Lossless Acceleration</title>
      <dc:creator>ifnodoraemon</dc:creator>
      <pubDate>Sun, 20 Sep 2026 04:51:57 +0000</pubDate>
      <link>https://dev.to/ifnodoraemon/speculative-decoding-in-production-from-draft-models-to-eagle-3-dynamic-trees-for-3x-5x-lossless-3j62</link>
      <guid>https://dev.to/ifnodoraemon/speculative-decoding-in-production-from-draft-models-to-eagle-3-dynamic-trees-for-3x-5x-lossless-3j62</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: The Memory-Bandwidth Curse of Autoregressive Decoding
&lt;/h2&gt;

&lt;p&gt;Before evaluating model acceleration techniques, we must confront the primary physical bottleneck of LLM inference: &lt;strong&gt;autoregressive generation is profoundly memory-bandwidth bound&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Consider serving an unquantized 70B parameter model in FP16 at single concurrency (Batch Size = 1):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The static model weights occupy &lt;strong&gt;140 GB&lt;/strong&gt; of VRAM;&lt;/li&gt;
&lt;li&gt;To generate a single new token, the GPU must fetch all 140 GB of weights from High Bandwidth Memory (HBM) into on-chip SRAM and registers;&lt;/li&gt;
&lt;li&gt;On a premier GPU delivering 3 TB/s of memory bandwidth, moving 140 GB requires approximately &lt;strong&gt;46 milliseconds&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;During those 46 milliseconds, the GPU Tensor Cores perform minimal floating-point operations. &lt;strong&gt;For over 95% of each decoding cycle, expensive compute units idle waiting on memory bus transfers.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph LR
    subgraph Traditional Autoregressive Decoding: Sequential Memory Stalls
        A1["Fetch 140GB Weights"] --&amp;gt; A2["Generate Token 1 (46ms)"]
        A2 --&amp;gt; A3["Fetch 140GB Weights"] --&amp;gt; A4["Generate Token 2 (46ms)"]
        A4 --&amp;gt; A5["Fetch 140GB Weights"] --&amp;gt; A6["Generate Token 3 (46ms)"]
    end
    subgraph Speculative Decoding: Speculative Drafting &amp;amp; Parallel Verification
        B1["Ultra-lightweight Draft Unit (5ms)"] --&amp;gt; B2["Speculatively generate 5 candidate tokens"]
        B2 --&amp;gt; B3["Single target forward pass (Fetch 140GB once, 48ms)"]
        B3 --&amp;gt; B4["Accept 4~5 tokens concurrently! (Throughput multiplied)"]
    end&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;To eliminate this memory bandwidth bottleneck, &lt;strong&gt;Speculative Decoding&lt;/strong&gt; shifts the workload from memory-bound sequential fetching to compute-bound parallel verification, generating multiple tokens in a single forward pass of the target model.&lt;/p&gt;




&lt;h2&gt;
  
  
  I. Mathematical Foundation: The Proof of Exact Lossless Invariance
&lt;/h2&gt;

&lt;p&gt;Engineers often ask: "Does guessing tokens with a smaller auxiliary model degrade output quality or drift the target probability distribution?"&lt;/p&gt;

&lt;p&gt;The answer is mathematically definitive: &lt;strong&gt;The output distribution of speculative decoding is provably and strictly 100% identical to the target base model.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Verification via Modified Rejection Sampling
&lt;/h3&gt;

&lt;p&gt;Let the target LLM be $M_p$ with conditional distribution $p(x)$, and the speculative draft mechanism be $M_q$ with distribution $q(x)$.&lt;/p&gt;

&lt;p&gt;Suppose the draft mechanism speculatively generates $K$ consecutive candidate tokens: $(x_1, x_2, \dots, x_K)$. The target model $M_p$ executes &lt;strong&gt;a single parallel forward pass&lt;/strong&gt; across all $K$ positions, evaluating the target probabilities: $p(x_1), p(x_2), \dots, p(x_K)$.&lt;/p&gt;

&lt;p&gt;For candidate token $x_k$, the engine executes a modified rejection sampling check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Calculate Acceptance Probability&lt;/strong&gt;:
$$\alpha = \min\left(1, \frac{p(x_k)}{q(x_k)}\right)$$&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sample Uniform Random Variable&lt;/strong&gt; $r \sim \text{Uniform}(0, 1)$:

&lt;ul&gt;
&lt;li&gt;If $r \le \alpha$, &lt;strong&gt;accept&lt;/strong&gt; token $x_k$;&lt;/li&gt;
&lt;li&gt;If $r &amp;gt; \alpha$, &lt;strong&gt;reject&lt;/strong&gt; token $x_k$ and terminate verification for subsequent tokens in this draft branch.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Residual Resampling upon Rejection&lt;/strong&gt;:
If a token is rejected at position $k$, the engine samples an alternate replacement token directly from the normalized positive residual distribution:
$$P_{resample}(x) = \frac{\max(0, p(x) - q(x))}{\sum_x \max(0, p(x) - q(x))}$$&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The Invariance Theorem&lt;/strong&gt;: As rigorously proven by Leviathan et al. (2023), marginalizing the joint distribution over the acceptance and residual branches recovers the exact target distribution $p(x)$. Whether employing greedy decoding or temperature-based stochastic sampling, &lt;strong&gt;output fidelity is mathematically preserved&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  II. The Four Generations of Speculative Decoding
&lt;/h2&gt;

&lt;p&gt;Speculative decoding has evolved through four major architectural generations:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Generation&lt;/th&gt;
&lt;th&gt;Architectural Principle&lt;/th&gt;
&lt;th&gt;Primary Strengths&lt;/th&gt;
&lt;th&gt;Bottlenecks &amp;amp; Limitations&lt;/th&gt;
&lt;th&gt;Key Citations&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gen 1: Dual-Model Drafting (Draft-Target)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A small dense model (e.g. Llama-3.2-1B) generates drafts for a 70B target model.&lt;/td&gt;
&lt;td&gt;Conceptually simple; uses off-the-shelf pre-trained models.&lt;/td&gt;
&lt;td&gt;The draft model is still a full transformer, competing for HBM memory bandwidth on busy GPUs.&lt;/td&gt;
&lt;td&gt;Leviathan et al. (2023)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gen 2: Parallel Multi-Head Prediction (Medusa)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Eliminates independent draft models; appends multiple parallel MLP prediction heads directly to the target model's final transformer layer.&lt;/td&gt;
&lt;td&gt;Zero additional model loading; no independent base model.&lt;/td&gt;
&lt;td&gt;Heads lack causal self-attention across draft positions, causing acceptance rates to collapse beyond 3 tokens.&lt;/td&gt;
&lt;td&gt;Medusa (2024)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gen 3: Feature Extrapolation &amp;amp; Dynamic Trees (EAGLE-1 / EAGLE-2)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Autoregressively extrapolates features in the penultimate hidden state and introduces &lt;strong&gt;Context-Aware Dynamic Draft Trees&lt;/strong&gt;.&lt;/td&gt;
&lt;td&gt;Smooth feature representations boost acceptance rates above 80%, yielding &amp;gt;3x speedup.&lt;/td&gt;
&lt;td&gt;Requires training a lightweight autoregressive head per target architecture.&lt;/td&gt;
&lt;td&gt;SafeAILab / Tsinghua (2024)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gen 4: Multi-Scale Semantic Fusion (EAGLE-3)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fuses low-, mid-, and high-level hidden representations across transformer depths into the dynamic tree.&lt;/td&gt;
&lt;td&gt;Significantly improves confidence on rare tokens and code syntax, unlocking &lt;strong&gt;4x~5.6x speedups&lt;/strong&gt;.&lt;/td&gt;
&lt;td&gt;Requires distributed offline synthetic feature extraction pipelines during training.&lt;/td&gt;
&lt;td&gt;EAGLE-3 (2025/2026)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  III. Dissecting EAGLE: Why Dynamic Draft Trees Dominate
&lt;/h2&gt;

&lt;p&gt;Tsinghua University's open-source framework &lt;strong&gt;&lt;a href="https://github.com/SafeAILab/EAGLE" rel="noopener noreferrer"&gt;EAGLE (SafeAILab/EAGLE)&lt;/a&gt;&lt;/strong&gt; has become the standard speculative backend across both vLLM and SGLang.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. From Linear Chains to Dynamic Trees
&lt;/h3&gt;

&lt;p&gt;Traditional speculative drafting predicts a single linear sequence: $Token_1 \to Token_2 \to Token_3$.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Linear Bottleneck&lt;/strong&gt;: If the model has 95% confidence on Token 1, but Token 2 represents an ambiguous conjunction with only 40% confidence, a rejection at Token 2 &lt;strong&gt;invalidates all subsequent tokens&lt;/strong&gt;, even if Tokens 3 and 4 were entirely accurate!&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TD
    subgraph Traditional Linear Drafting (Cascade Failure)
        L1["Token A (95% Confidence - Match)"] --&amp;gt; L2["Token B (40% - Rejected!)"]
        L2 -.-&amp;gt;|Downstream Discarded| L3["Token C (Accurate)"]
        L2 -.-&amp;gt;|Downstream Discarded| L4["Token D (Accurate)"]
    end
    subgraph EAGLE-2/3: Context-Aware Dynamic Draft Tree (Tree Attention)
        T0["Root Context"] --&amp;gt; T1["Candidate Token A (95%)"]
        T1 --&amp;gt; T2["Branch B1 (45%)"]
        T1 --&amp;gt; T3["Branch B2 (40%)"]
        T2 --&amp;gt; T4["Branch C1 (90%)"]
        T3 --&amp;gt; T5["Branch C2 (85%)"]
    end&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  2. The Tree Attention Verification Mechanism
&lt;/h3&gt;

&lt;p&gt;EAGLE flattens the multi-branch candidate tree into a single concatenated sequence, using a &lt;strong&gt;2D Tree-Attention Mask&lt;/strong&gt; to allow the target model to verify all candidate branches in &lt;strong&gt;one single forward pass&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If branch $B_1$ is rejected but branch $B_2$ matches, the engine accepts path $B_2 \to C_2$ seamlessly.&lt;/li&gt;
&lt;li&gt;Dynamically pruning unlikely paths keeps the average accepted tokens per step ($\tau$) reliably between &lt;strong&gt;3.5 and 4.8&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  IV. Production Deployment: vLLM &amp;amp; SGLang Integration
&lt;/h2&gt;

&lt;p&gt;Here is how to deploy EAGLE speculative decoding for &lt;code&gt;Qwen/Qwen2.5-72B-Instruct&lt;/code&gt; in production containers.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Deploying with vLLM
&lt;/h3&gt;

&lt;p&gt;vLLM natively integrates EAGLE via the &lt;code&gt;--speculative-model&lt;/code&gt; parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vllm serve Qwen/Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tensor-parallel-size&lt;/span&gt; 4 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--gpu-memory-utilization&lt;/span&gt; 0.90 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-model-len&lt;/span&gt; 8192 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--speculative-model&lt;/span&gt; yuhuili/EAGLE-Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--num-speculative-tokens&lt;/span&gt; 5 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--speculative-draft-tensor-parallel-size&lt;/span&gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--port&lt;/span&gt; 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Flag Rationale&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--speculative-model&lt;/code&gt;: Points to the dedicated EAGLE lightweight head weights on HuggingFace (~500MB to 1GB);&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--num-speculative-tokens 5&lt;/code&gt;: Drafting 5 tokens balances verification throughput with GPU latency;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--speculative-draft-tensor-parallel-size 1&lt;/code&gt;: The draft head is small enough to run on a single GPU without cross-GPU communication overhead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Deploying with SGLang
&lt;/h3&gt;

&lt;p&gt;SGLang provides native tree-search kernels for EAGLE (for architectural comparisons, see our &lt;a href="https://blog.llmgo.top/en/articles/sglang-vs-vllm-architecture/" rel="noopener noreferrer"&gt;SGLang vs vLLM Architecture Breakdown&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; sglang.launch_server &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--model-path&lt;/span&gt; Qwen/Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--speculative-algorithm&lt;/span&gt; EAGLE &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--speculative-draft&lt;/span&gt; yuhuili/EAGLE-Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--speculative-num-steps&lt;/span&gt; 5 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--speculative-eagle-topk&lt;/span&gt; 4 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--speculative-num-draft-tokens&lt;/span&gt; 16 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tp&lt;/span&gt; 4 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--port&lt;/span&gt; 30000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: &lt;code&gt;--speculative-eagle-topk 4&lt;/code&gt; and &lt;code&gt;--speculative-num-draft-tokens 16&lt;/code&gt; activate dynamic tree exploration with depth 5 across 16 draft nodes.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  V. When Does Speculative Decoding Fail? The Slowdown Trap
&lt;/h2&gt;

&lt;p&gt;Speculative decoding is not universally beneficial. Under certain operating conditions, it can cause an inadvertent &lt;strong&gt;performance regression (Negative Speedup)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TD
    Start["Analyze Serving Workload"] --&amp;gt; Q1{"What is the target concurrency level?"}
    Q1 --&amp;gt;|"High Concurrency (Tensor Cores Already 100% Saturated)"| Slowdown["⚠️ Disable Speculative Decoding&amp;lt;br/&amp;gt;(Verification passes steal FLOPs from normal batches, reducing total throughput)"]
    Q1 --&amp;gt;|"Low-to-Medium Concurrency (Latencies are Memory-Bound)"| Q2{"What is the entropy/predictability of the generation task?"}

    Q2 --&amp;gt;|"High-Entropy Content (Open-ended creative writing / random keys)"| Fragile["⚠️ Acceptance rate drops below 30%&amp;lt;br/&amp;gt;(Draft overhead exceeds verification gains)"]
    Q2 --&amp;gt;|"Structured &amp;amp; Deterministic (Code, JSON, Math, Translation)"| SuperFast["🚀 Enable EAGLE&amp;lt;br/&amp;gt;(Acceptance rate &amp;gt;80%, 3.5x~5x acceleration)"]&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  The Compute Saturation Boundary
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Low Concurrency (Concurrency $\le 16$)&lt;/strong&gt;: GPU Tensor Cores sit underutilized during decoding. Speculative verification leverages idle compute to accelerate Inter-Token Latency (ITL) by 60%~75%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-Throughput Concurrency (Concurrency $\ge 128$)&lt;/strong&gt;: Batches are already dense enough to saturate memory bandwidth into a Compute-Bound state. Adding speculative verification passes can &lt;strong&gt;reduce overall system throughput by 10%~15%&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Frequently Asked Questions (FAQ)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Q1: Does speculative decoding require retraining the base model?
&lt;/h3&gt;

&lt;p&gt;No. The base foundation model remains 100% frozen. EAGLE trains an auxiliary single-layer decoder head on frozen intermediate feature vectors, requiring only 0.5% to 1% of the base model's parameters and a few hours of commodity GPU training.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2: Can speculative decoding be combined with FP8 weight quantization?
&lt;/h3&gt;

&lt;p&gt;Yes, and this represents the standard high-performance inference stack in 2026. Deploying FP8/AWQ weights fits models within tight VRAM constraints (see our &lt;a href="https://blog.llmgo.top/en/articles/quantization-hands-on-guide/" rel="noopener noreferrer"&gt;Practical Quantization Guide&lt;/a&gt;), while an EAGLE speculative head bypasses memory-bandwidth bottlenecks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3: Why does real-world speedup sometimes lag behind theoretical benchmarks?
&lt;/h3&gt;

&lt;p&gt;Realized acceleration is strictly bounded by the &lt;strong&gt;empirical acceptance rate $\alpha$&lt;/strong&gt;. In programming languages (Python/Java) and JSON extraction where syntax is highly structured, acceptance rates exceed 85%, yielding 4x+ speedups. In open-ended conversational domains with high sampling temperatures ($T \ge 1.0$), acceptance rates drop toward 50%, yielding more modest 1.8x~2.2x speedups.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://blog.llmgo.top/en/articles/speculative-decoding-eagle-guide/" rel="noopener noreferrer"&gt;Nobita Talks AI&lt;/a&gt; on blog.llmgo.top.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>performanceacceleration</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>SGLang vs vLLM Architecture Showdown: RadixAttention, Structured Decoding, and High-Concurrency Benchmarks</title>
      <dc:creator>ifnodoraemon</dc:creator>
      <pubDate>Sun, 20 Sep 2026 04:51:51 +0000</pubDate>
      <link>https://dev.to/ifnodoraemon/sglang-vs-vllm-architecture-showdown-radixattention-structured-decoding-and-high-concurrency-55fj</link>
      <guid>https://dev.to/ifnodoraemon/sglang-vs-vllm-architecture-showdown-radixattention-structured-decoding-and-high-concurrency-55fj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: The Dual Titans of Open-Source Inference
&lt;/h2&gt;

&lt;p&gt;Throughout 2024 and early 2025, &lt;strong&gt;vLLM&lt;/strong&gt;, developed by UC Berkeley's Sky Computing Lab, established itself as the undisputed de facto standard for open-source LLM inference serving, largely due to its pioneering PagedAttention algorithm.&lt;/p&gt;

&lt;p&gt;However, as 2026 arrived, the paradigm shifted toward agentic workflows, multi-turn tool-calling chains, and strict JSON Schema constraints. In this landscape, another framework from Berkeley's LMSYS team—&lt;strong&gt;&lt;a href="https://github.com/sgl-project/sglang" rel="noopener noreferrer"&gt;SGLang&lt;/a&gt;&lt;/strong&gt;—rose rapidly to challenge vLLM's dominance.&lt;/p&gt;

&lt;p&gt;Engineering teams across the industry now face a critical architecture dilemma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Given that vLLM supports Automatic Prefix Caching (APC) and continuous batching, why migrate to SGLang?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How does SGLang's RadixAttention physically outperform traditional block-level PagedAttention?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What is the true Time-To-First-Token (TTFT) and throughput delta in multi-turn Agent loops and structured JSON extraction?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article moves past marketing claims to analyze the &lt;strong&gt;underlying memory data structures&lt;/strong&gt; and &lt;strong&gt;scheduler-level compilation pipelines&lt;/strong&gt;, supported by empirical benchmarks on an 8x NVIDIA H100 SXM cluster.&lt;/p&gt;




&lt;h2&gt;
  
  
  I. Core Memory Architecture: PagedAttention vs. RadixAttention
&lt;/h2&gt;

&lt;p&gt;Because autoregressive generation is fundamentally memory-bandwidth bound, the core differentiator of any inference engine is how efficiently it allocates, retains, and reuses the &lt;strong&gt;KV Cache&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TD
    subgraph vLLM: PagedAttention (Block Paging &amp;amp; Flat Matching)
        V1["Incoming Prompt Tokens"] --&amp;gt; V2["Slice into Fixed Blocks (e.g. 16 Tokens)"]
        V2 --&amp;gt; V3["Hash Map Lookup for Matching Block Sequences"]
        V3 --&amp;gt; V4["Discrete Memory Mapping (Similar to OS Virtual Memory)"]
    end
    subgraph SGLang: RadixAttention (Dynamic Tree-Structured Caching)
        S1["Incoming Prompt Tokens"] --&amp;gt; S2["Traverse Radix Tree Top-Down"]
        S2 --&amp;gt; S3{"Shared Sub-tree Match?"}
        S3 --&amp;gt;|"Full Match"| S4["Zero-Overhead Pointer Reuse to KV Pages"]
        S3 --&amp;gt;|"Partial Match"| S5["Split Node at Exact Divergence Point"]
        S4 --&amp;gt; S6["LRU Tree Pruning Strategy"]
        S5 --&amp;gt; S6
    end&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  1. vLLM's PagedAttention and Flat Hash Caching
&lt;/h3&gt;

&lt;p&gt;vLLM's breakthrough was adapting virtual memory paging principles from operating systems to GPU tensors. By dividing dynamic KV caches into fixed-size "blocks" (typically 16 or 32 tokens) linked via page tables, it eliminated memory fragmentation.&lt;/p&gt;

&lt;p&gt;To achieve prompt reuse, vLLM introduced &lt;strong&gt;Automatic Prefix Caching (APC)&lt;/strong&gt; based on a hash-chained cache pool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a request arrives, the engine computes cryptographic hashes across sequential token blocks.&lt;/li&gt;
&lt;li&gt;It checks the cache pool for matching blocks and chains them together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Engineering Limitation&lt;/strong&gt;: vLLM organizes cache blocks &lt;strong&gt;linearly and flatly&lt;/strong&gt;. In branching workflows (such as Monte Carlo Tree Search, Agent rollbacks, or prompts with interspersed variables), flat hashing struggles to capture dynamic tree forks. Blocks often miss the cache or are prematurely evicted.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. SGLang's RadixAttention: The Tree-Structured Paradigm
&lt;/h3&gt;

&lt;p&gt;SGLang fundamentally reimagines memory caching by introducing &lt;strong&gt;RadixAttention&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of treating the KV cache as disjointed linear blocks, it organizes all active and retained KV caches into a global &lt;strong&gt;Radix Tree (Compressed Prefix Trie)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Paths Represent Prefixes&lt;/strong&gt;: The root node represents an empty prompt. Every directed edge carries a sequence of tokens, while internal nodes and leaves point to physical GPU memory pages holding the corresponding KV tensors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptive Node Splitting&lt;/strong&gt;: If two requests share a lengthy System Prompt but diverge on an intermediate tool output, the Radix Tree splits the node at the exact token divergence point. Both requests share the parent node's KV cache with zero redundancy, allocating memory only for the differential branch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Topological LRU Eviction&lt;/strong&gt;: When GPU VRAM approaches capacity, SGLang prunes the least recently used &lt;strong&gt;leaf nodes&lt;/strong&gt;, allowing heavily shared system prompts and root nodes to remain resident indefinitely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Benchmark Difference&lt;/strong&gt;: For one-off stateless prompts, both engines perform similarly. But in &lt;strong&gt;multi-turn chat, iterative tree searches, and Agent workflows with shared system prompts&lt;/strong&gt;, SGLang's cache hit rate surges from vLLM's 30%~45% up to &lt;strong&gt;70%~85%&lt;/strong&gt;, cutting TTFT by up to 4x. For the underlying mathematical foundations of memory compression, see our analysis on &lt;a href="https://blog.llmgo.top/en/articles/kimi-kda-deepseek-mla-architecture/" rel="noopener noreferrer"&gt;Kimi KDA and DeepSeek MLA Architecture&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  II. Structured Decoding: External Logit Masking vs. Scheduler-Level FSM Compilation
&lt;/h2&gt;

&lt;p&gt;In production environments, over 60% of API endpoints require strict compliance with &lt;strong&gt;JSON Schemas, regex patterns, or domain-specific languages (DSLs)&lt;/strong&gt;. The two frameworks handle this via completely different pipelines.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Evaluation Vector&lt;/th&gt;
&lt;th&gt;vLLM (via Outlines / Guided Decoding)&lt;/th&gt;
&lt;th&gt;SGLang (Scheduler-Native Compressed FSM)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Core Mechanism&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;External Logit Masking&lt;/strong&gt;: At each forward step, an external regex state machine computes valid tokens and masks invalid logits to $-\infty$ prior to Softmax.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Compressed Finite State Machine (FSM)&lt;/strong&gt;: Compiles the schema directly into the C++/CUDA scheduler core, detecting deterministic tokens to trigger immediate jump-forward bypass.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Execution Layer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Interceptor wrapper between the API server and scheduler&lt;/td&gt;
&lt;td&gt;Deeply compiled inside the inner CUDA forward loop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Literal Generation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;For static syntax like &lt;code&gt;{"status": "success", "data": [&lt;/code&gt;, the model must still execute full autoregressive matrix multiplications token-by-token.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Jump-Forward Decoding&lt;/strong&gt;: Identifies deterministic strings and injects them in a single step, skipping autoregressive forward passes completely!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Throughput Under Load&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;At 64+ concurrent requests, CPU overhead from evaluating massive token masks (e.g. 128k vocabulary) bottlenecks the system, dropping throughput by &amp;gt;40%.&lt;/td&gt;
&lt;td&gt;FSM transitions consume &amp;lt;5 microseconds on CPU. Throughput under strict JSON constraints remains within 95% of unconstrained generation.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;sequenceDiagram
    participant Client as Application Client
    participant Scheduler as SGLang Scheduler
    participant GPU as GPU Tensor Cores

    Client-&amp;gt;&amp;gt;Scheduler: Request (Strict JSON Schema Enforced)
    Note over Scheduler: Compiles JSON Schema into Optimized FSM
    Scheduler-&amp;gt;&amp;gt;GPU: Generate dynamic key '{"order_id": "'
    Note over Scheduler: FSM detects subsequent quotes and commas as deterministic
    Scheduler--&amp;gt;&amp;gt;GPU: Execute Jump-forward Injection (Bypasses Matrix Multiplication)
    GPU-&amp;gt;&amp;gt;Scheduler: Return dynamic token sequence
    Scheduler-&amp;gt;&amp;gt;Client: Stream valid JSON (Up to 2.5x throughput gain)&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  III. 8x H100 Production Cluster Benchmarks
&lt;/h2&gt;

&lt;p&gt;To provide concrete empirical data, we evaluated both engines on an enterprise node equipped with &lt;strong&gt;8x NVIDIA H100 SXM5 80GB GPUs&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Benchmark Environment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compute&lt;/strong&gt;: 8x H100 SXM 80GB (NVLink 4.0, 900 GB/s bidirectional interconnect bandwidth)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Host&lt;/strong&gt;: Dual Intel Xeon Platinum 8480+ (112 cores), 1TB DDR5 RAM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model&lt;/strong&gt;: &lt;code&gt;Qwen/Qwen2.5-72B-Instruct&lt;/code&gt; (FP8 quantization)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency Sweep&lt;/strong&gt;: Concurrency levels $C \in [1, 16, 64, 128, 256]$&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Scenario A: Stateless General QA (Prompt: 2048 Tokens, Output: 512 Tokens, 0% Prefix Overlap)
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Measures raw operator kernel efficiency and continuous batching throughput without caching advantages.&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concurrency ($C$)&lt;/th&gt;
&lt;th&gt;vLLM Throughput (Tokens/s)&lt;/th&gt;
&lt;th&gt;SGLang Throughput (Tokens/s)&lt;/th&gt;
&lt;th&gt;vLLM P99 TTFT (ms)&lt;/th&gt;
&lt;th&gt;SGLang P99 TTFT (ms)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;48.2&lt;/td&gt;
&lt;td&gt;49.1&lt;/td&gt;
&lt;td&gt;82&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;690.4&lt;/td&gt;
&lt;td&gt;702.1&lt;/td&gt;
&lt;td&gt;145&lt;/td&gt;
&lt;td&gt;140&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;2,410.8&lt;/td&gt;
&lt;td&gt;2,480.3&lt;/td&gt;
&lt;td&gt;420&lt;/td&gt;
&lt;td&gt;410&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;4,120.5&lt;/td&gt;
&lt;td&gt;4,190.2&lt;/td&gt;
&lt;td&gt;890&lt;/td&gt;
&lt;td&gt;860&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Verdict&lt;/strong&gt;: In stateless, non-overlapping workloads, performance is essentially identical. SGLang maintains a negligible 1%~3% advantage due to FlashInfer kernel tuning, while vLLM demonstrates solid, predictable behavior. For advanced vLLM tuning, consult our &lt;a href="https://blog.llmgo.top/en/articles/vllm-serving-guide/" rel="noopener noreferrer"&gt;vLLM Production Serving Guide&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Scenario B: Multi-Turn Agent Tool Calling (Prompt: 4096 Tokens, 75% Prefix Overlap)
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Simulates an enterprise agent conversational loop with rich tool declarations and shared conversation history.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Benchmark Results (Concurrency = 64, Prefix Overlap = 75%):
------------------------------------------------------------
Metric                         vLLM (APC Active)   SGLang (RadixTree)   Advantage
Median TTFT (P50)                   380 ms              85 ms           SGLang 4.47x Faster 🚀
Tail Latency TTFT (P99)           1,250 ms             280 ms           SGLang 4.46x Faster 🚀
KV Cache Hit Rate                    41.2%               78.6%          Almost 2x Hit Rate
Total Output Throughput (Tokens/s)   3,120               5,430          SGLang +74% Gain
------------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Architectural Analysis&lt;/strong&gt;:&lt;br&gt;
In multi-turn execution, vLLM's APC frequently misses cache hits because user variations disrupt flat hash alignment across non-contiguous blocks. SGLang's RadixTree locks the parent system prompt and historical turns into shared branches, executing prefill almost instantaneously.&lt;/p&gt;


&lt;h3&gt;
  
  
  4. Scenario C: Strict JSON Schema Extraction
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Forces the model to parse complex unstructured financial filings into an exact 20-field nested JSON schema.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Throughput vs. Concurrency Under Structured Constraints:
- Unconstrained Generation: Both engines reach ~4,200 tokens/s at Concurrency 128
- Enforcing Strict JSON Schema:
  * vLLM (Guided Decoding): Throughput drops to 2,350 tokens/s (CPU logit masking saturation)
  * SGLang (FSM Jump-forward): Throughput sustains 3,980 tokens/s (Less than 6% degradation)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  IV. Production Deployment Recipes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. vLLM Production Configuration (Recommended for Broadest Compatibility)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vllm serve Qwen/Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tensor-parallel-size&lt;/span&gt; 8 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--gpu-memory-utilization&lt;/span&gt; 0.92 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-model-len&lt;/span&gt; 16384 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-prefix-caching&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-chunked-prefill&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-num-seqs&lt;/span&gt; 256 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--quantization&lt;/span&gt; fp8 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--port&lt;/span&gt; 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. SGLang Production Configuration (Recommended for Agent &amp;amp; Structured Workloads)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; sglang.launch_server &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--model-path&lt;/span&gt; Qwen/Qwen2.5-72B-Instruct &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tp&lt;/span&gt; 8 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--mem-fraction-static&lt;/span&gt; 0.90 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--context-length&lt;/span&gt; 16384 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-flashinfer&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--schedule-policy&lt;/span&gt; lpm &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--port&lt;/span&gt; 30000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: &lt;code&gt;--schedule-policy lpm&lt;/code&gt; activates Longest Prefix Match scheduling, maximizing radix tree hit rates.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  V. Enterprise Architecture Decision Framework
&lt;/h2&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TD
    Start["Evaluate Workload Requirements"] --&amp;gt; Q1{"Do queries involve multi-turn agent loops, heavy prefix sharing, or strict JSON output?"}
    Q1 --&amp;gt;|"Yes (Agentic / RAG / JSON-Heavy)"| BranchSGLang["Select SGLang"]
    Q1 --&amp;gt;|"No (Stateless QA / Batch Processing)"| Q2{"Are you deploying on non-standard accelerators or obscure model architectures?"}

    Q2 --&amp;gt;|"Yes (Custom NPUs / Exotic Topologies)"| BranchVLLM["Select vLLM (Widest Ecosystem Support)"]
    Q2 --&amp;gt;|"No (Standard NVIDIA/AMD GPUs, Mainstream LLMs)"| Q3{"Does your ops pipeline require turn-key Helm charts and commercial K8s operators?"}

    Q3 --&amp;gt;|"Yes (Prioritize Turn-Key Stability)"| BranchVLLM
    Q3 --&amp;gt;|"No (Prioritize Latency &amp;amp; Throughput)"| BranchSGLang&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  Frequently Asked Questions (FAQ)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Q1: Does RadixAttention introduce CPU overhead from frequent tree splits?
&lt;/h3&gt;

&lt;p&gt;No. Radix tree operations (lookups, splits, inserts, and pointer swaps) are executed via optimized C++ and Rust structures in host memory. In typical workloads of 100 to 200 concurrent requests, tree operations execute in &lt;strong&gt;microseconds ($\mu s$)&lt;/strong&gt;, rendering CPU overhead negligible compared to multi-millisecond GPU matrix multiplications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2: Can vLLM simply adopt RadixAttention in a future release?
&lt;/h3&gt;

&lt;p&gt;Not without a complete architectural rewrite. vLLM's scheduler and distributed memory managers are deeply coupled to the &lt;code&gt;PagedBlock&lt;/code&gt; abstraction, which coordinates cross-GPU synchronization across tensor and pipeline parallelism ranks. Transitioning vLLM to a dynamic directed acyclic graph (DAG) prefix tree would require redesigning its core scheduler. Both frameworks will maintain distinct architectures for the foreseeable future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3: Does SGLang support model quantization and speculative decoding?
&lt;/h3&gt;

&lt;p&gt;Yes. SGLang natively supports FP8, AWQ, GPTQ, and Marlin kernels (for quantization trade-offs, review our &lt;a href="https://blog.llmgo.top/en/articles/quantization-hands-on-guide/" rel="noopener noreferrer"&gt;Practical Quantization Guide&lt;/a&gt; and &lt;a href="https://blog.llmgo.top/en/articles/quantization-precision-guide/" rel="noopener noreferrer"&gt;Quantization Precision Guide&lt;/a&gt;). Furthermore, SGLang natively integrates dynamic tree-based speculative decoding via EAGLE.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://blog.llmgo.top/en/articles/sglang-vs-vllm-architecture/" rel="noopener noreferrer"&gt;Nobita Talks AI&lt;/a&gt; on blog.llmgo.top.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>inferencesystems</category>
      <category>machinelearning</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Test-Time Compute and GRPO in Practice: From PPO to Critic-Free Reinforcement Learning</title>
      <dc:creator>ifnodoraemon</dc:creator>
      <pubDate>Sun, 20 Sep 2026 03:13:28 +0000</pubDate>
      <link>https://dev.to/ifnodoraemon/test-time-compute-and-grpo-in-practice-from-ppo-to-critic-free-reinforcement-learning-4gpn</link>
      <guid>https://dev.to/ifnodoraemon/test-time-compute-and-grpo-in-practice-from-ppo-to-critic-free-reinforcement-learning-4gpn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: The Pre-training Wall and the Dawn of Test-Time Scaling
&lt;/h2&gt;

&lt;p&gt;For the past several years, the foundational law of frontier LLM development was Chinchilla's &lt;strong&gt;Pre-training Scaling Laws&lt;/strong&gt;: stack deeper transformer layers, ingest multi-trillion token corpora, and burn increasingly massive GPU clusters.&lt;/p&gt;

&lt;p&gt;However, entering 2026, this brute-force approach has encountered formidable physical and thermodynamic bottlenecks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Human Knowledge Depletion Wall&lt;/strong&gt;: High signal-to-noise public internet text has been virtually exhausted. Naive ingestion of low-quality synthetic web dumps risks "model collapse" and entropy degeneration during unsupervised pre-training.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diminishing Returns on Model Scale&lt;/strong&gt;: Pushing model parameters from 70B to 700B incurs exponential spikes in capital expenditures, cluster interconnect overhead, and power consumption, yet returns only marginal improvements on everyday reasoning.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As pre-training scaling slows, frontier reasoning engines (such as OpenAI o1/o3 and DeepSeek-R1) have ignited a secondary growth curve: &lt;strong&gt;Test-Time Compute Scaling Laws&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph LR
    subgraph Traditional Paradigm: One-Shot Pre-training Inference
        A1["Complex Math/Coding Prompt"] --&amp;gt; A2["70B~400B Dense Base LLM"] --&amp;gt; A3["Greedy Decoding (Prone to Hallucinations)"]
    end
    subgraph Reasoning Paradigm: Test-Time Compute Scaling
        B1["Complex Math/Coding Prompt"] --&amp;gt; B2["Compact Base Model"] --&amp;gt; B3["Extended Chain-of-Thought (CoT)"] --&amp;gt; B4["Self-Verification &amp;amp; Backtracking"] --&amp;gt; B5["Deterministic Accurate Solution"]
    end&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Rather than spending millions of dollars during pre-training to memorize answers to every conceivable question, test-time scaling trains models to allocate dynamic computation at inference time—thinking, calculating, and self-correcting before providing a response.&lt;/p&gt;




&lt;h2&gt;
  
  
  I. The Three Regimes of Test-Time Compute Scaling
&lt;/h2&gt;

&lt;p&gt;In modern literature, extending test-time compute falls into three primary architectural regimes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scaling Regime&lt;/th&gt;
&lt;th&gt;Core Mechanism&lt;/th&gt;
&lt;th&gt;Primary Compute Bottleneck&lt;/th&gt;
&lt;th&gt;Representative Work&lt;/th&gt;
&lt;th&gt;Bottlenecks &amp;amp; Failure Modes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1. Sequential CoT Expansion&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The model outputs multi-thousand token chains of thought (&lt;code&gt;&amp;lt;think&amp;gt; ... &amp;lt;/think&amp;gt;&lt;/code&gt;), enabling backtracking and scratchpad verification.&lt;/td&gt;
&lt;td&gt;Autoregressive decoding latency&lt;/td&gt;
&lt;td&gt;DeepSeek-R1, OpenAI o1&lt;/td&gt;
&lt;td&gt;Prone to "overthinking" loops on trivial prompts; latency increases substantially.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2. Leaf-level Sampling &amp;amp; Voting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Parallel sampling of $N$ diverse paths, combined with majority voting or verifiers.&lt;/td&gt;
&lt;td&gt;Batch concurrency capacity&lt;/td&gt;
&lt;td&gt;Best-of-N, Self-Consistency&lt;/td&gt;
&lt;td&gt;Search space is unguided; incorrect trajectories waste full GPU decode cycles.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3. Prefix-level Search with PRMs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Process Reward Models (PRMs) score intermediate steps within tree search (Beam Search / MCTS).&lt;/td&gt;
&lt;td&gt;Step-level verifier evaluation&lt;/td&gt;
&lt;td&gt;AlphaGo-style MCTS, Step-PRMs&lt;/td&gt;
&lt;td&gt;Step-level PRM annotations are costly; imperfect verifiers invite "reward hacking."&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The breakthrough of DeepSeek-R1 lies in fusing &lt;strong&gt;sequential chain-of-thought expansion&lt;/strong&gt; with &lt;strong&gt;critic-free reinforcement learning&lt;/strong&gt;, proving that pure rule-based RL can induce deep reasoning behaviors without manually engineered step-by-step PRMs.&lt;/p&gt;




&lt;h2&gt;
  
  
  II. From PPO to GRPO: Why Traditional RLHF Breaks on Long Reasoning Traces
&lt;/h2&gt;

&lt;p&gt;For years, &lt;strong&gt;PPO (Proximal Policy Optimization)&lt;/strong&gt; was the standard algorithm for post-training alignment. However, when applied to reasoning models with 10k+ token outputs, PPO collapses under severe infrastructure and mathematical constraints.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Quad-Model VRAM Explosion
&lt;/h3&gt;

&lt;p&gt;A classic PPO training setup requires hosting and synchronizing &lt;strong&gt;four distinct neural networks&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Actor Model ($\pi_\theta$)&lt;/strong&gt;: The trainable policy generating tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Critic Model ($V_\phi$)&lt;/strong&gt;: Typically matching the Actor's size, tasked with estimating scalar state values $V(s)$.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reference Model ($\pi_{ref}$)&lt;/strong&gt;: A frozen copy computing per-token KL divergence to prevent policy drift.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reward Model ($R_\psi$)&lt;/strong&gt;: A frozen network scoring terminal outputs.
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TD
    subgraph Traditional PPO Architecture
        P1["Actor Model (Trainable)"]
        P2["Critic Model (Trainable - Massive VRAM)"]
        P3["Reference Model (Frozen)"]
        P4["Reward Model (Frozen)"]
    end
    subgraph GRPO Architecture
        G1["Actor Model (Trainable)"]
        G2["Ref Weights / Analytical KL Calculation"]
        G3["Deterministic Environment (Python Sandbox / Unit Tests / Matcher)"]
    end&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;In a 70B parameter setup, loading the Actor and Critic alongside their respective AdamW optimizer states easily demands over &lt;strong&gt;600GB of VRAM&lt;/strong&gt;. This forces teams to deploy complex tensor and pipeline parallelism merely to fit the training loop. For low-level driver and memory bus topology guidelines, consult our &lt;a href="https://blog.llmgo.top/en/articles/nvidia-gpu-package-architecture/" rel="noopener noreferrer"&gt;NVIDIA GPU Package Architecture Deep Dive&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Value Function Drift Across Long Horizons
&lt;/h3&gt;

&lt;p&gt;When a model reasons through intricate mathematical proofs, trajectories stretch across 8,000 to 16,000 tokens. Training a Critic to accurately predict the expected discounted return at every intermediate token is mathematically fragile. Critic errors amplify gradient variance, causing loss values to explode into NaNs.&lt;/p&gt;




&lt;h2&gt;
  
  
  III. Mathematical Derivation of GRPO: The Critic-Free Revolution
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GRPO (Group Relative Policy Optimization)&lt;/strong&gt; was pioneered by DeepSeek in the DeepSeekMath paper and scaled in DeepSeek-R1.&lt;/p&gt;

&lt;p&gt;Its core thesis is remarkably elegant: &lt;strong&gt;Eliminate the Critic network entirely, sample a group of completions for each prompt, and use the group's empirical distribution as the baseline.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Group Sampling and Normalized Advantage
&lt;/h3&gt;

&lt;p&gt;For any input query $q$, the policy $\pi_{\theta_{old}}$ generates a group of $G$ distinct candidate completions:&lt;/p&gt;

&lt;p&gt;$${o_1, o_2, \dots, o_G} \sim \pi_{\theta_{old}}(q)$$&lt;/p&gt;

&lt;p&gt;The verification environment (e.g., a regex answer parser or a compiler test runner) assigns scalar rewards to each completion:&lt;/p&gt;

&lt;p&gt;$${r_1, r_2, \dots, r_G}$$&lt;/p&gt;

&lt;p&gt;Rather than evaluating an absolute value network $V(s)$, GRPO computes the relative advantage $A_i$ of completion $o_i$ normalized against its peers:&lt;/p&gt;

&lt;p&gt;$$A_i = \frac{r_i - \text{mean}({r_1, \dots, r_G})}{\text{std}({r_1, \dots, r_G}) + \epsilon}$$&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If $o_i$ outperforms the group average, $A_i &amp;gt; 0$, reinforcing the token trajectory.&lt;/li&gt;
&lt;li&gt;If $o_i$ underperforms, $A_i &amp;lt; 0$, penalizing the trajectory.&lt;/li&gt;
&lt;li&gt;Normalizing by the standard deviation dynamically stabilizes variance across batches.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. The GRPO Objective Function
&lt;/h3&gt;

&lt;p&gt;Retaining the clipped surrogate mechanism from PPO, GRPO optimizes the following objective:&lt;/p&gt;

&lt;p&gt;$$\mathcal{J}&lt;em&gt;{GRPO}(\theta) = \mathbb{E}&lt;/em&gt;{q \sim P(Q), {o_i}&lt;em&gt;{i=1}^G \sim \pi&lt;/em&gt;{\theta_{old}}(q)} \left[ \frac{1}{G} \sum_{i=1}^{G} \frac{1}{|o_i|} \sum_{t=1}^{|o_i|} \left( \min \left( \frac{\pi_\theta(o_{i,t} \mid q, o_{i,&amp;lt;t})}{\pi_{\theta_{old}}(o_{i,t} \mid q, o_{i,&amp;lt;t})} A_{i,t}, \; \text{clip}\left(\frac{\pi_\theta(o_{i,t} \mid q, o_{i,&amp;lt;t})}{\pi_{\theta_{old}}(o_{i,t} \mid q, o_{i,&amp;lt;t})}, 1-\epsilon, 1+\epsilon\right) A_{i,t} \right) - \beta D_{KL}(\pi_\theta \parallel \pi_{ref}) \right) \right]$$&lt;/p&gt;

&lt;p&gt;where the per-token KL divergence approximation is computed directly:&lt;/p&gt;

&lt;p&gt;$$D_{KL} = \frac{\pi_{ref}(o_{i,t} \mid \cdot)}{\pi_\theta(o_{i,t} \mid \cdot)} - \log \frac{\pi_{ref}(o_{i,t} \mid \cdot)}{\pi_\theta(o_{i,t} \mid \cdot)} - 1$$&lt;/p&gt;

&lt;p&gt;This architectural shift achieves two immediate advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Over 50% Reduction in Training Memory&lt;/strong&gt;: Eliminating the Critic model discards its weights, gradients, and optimizer states.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Value-Model Misalignment&lt;/strong&gt;: The baseline is derived directly from empirical sampling statistics, providing stable convergence.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  IV. The "Aha Moment" and the Emergence of Self-Reflection
&lt;/h2&gt;

&lt;p&gt;In the DeepSeek-R1-Zero experiment, researchers demonstrated that &lt;strong&gt;without a single human SFT demonstration&lt;/strong&gt;, training a pure base model with GRPO induced complex reasoning behaviors:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Deterministic Rule-Based Rewards
&lt;/h3&gt;

&lt;p&gt;Instead of relying on a learned neural reward model (which often suffers from reward gaming), the environment enforces strict rule-based verifiers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Accuracy Reward&lt;/strong&gt;: Verifies if the mathematical result matches ground truth or if the unit tests pass in a sandboxed interpreter (1.0 for success, 0.0 for failure).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Format Reward&lt;/strong&gt;: Enforces that reasoning is encapsulated strictly between &lt;code&gt;&amp;lt;think&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;/think&amp;gt;&lt;/code&gt; tags, with the final answer inside &lt;code&gt;&amp;lt;answer&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Spontaneous Emergence of Self-Correction
&lt;/h3&gt;

&lt;p&gt;After several thousand iterations, as trajectory length expanded, logs revealed models discovering self-correction unprompted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: Is 9.11 larger than 9.9?
Assistant:
&amp;lt;think&amp;gt;
First, compare 9.11 and 9.9.
The integer part is both 9.
Now compare the tenths place: 9.11 has 1 in the tenths place, while 9.9 has 9 in the tenths place.
Wait! Let me rethink this... Am I confusing decimal places with software version numbers?
In software engineering, v9.11 is newer than v9.9, but mathematically, 9.9 = 9.90.
Since 9.90 &amp;gt; 9.11, 9.9 is strictly larger.
Let me double check the calculation: 9.9 - 9.11 = 0.79 &amp;gt; 0. Yes, absolutely correct.
&amp;lt;/think&amp;gt;
&amp;lt;answer&amp;gt;
No, 9.9 is larger than 9.11.
&amp;lt;/answer&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From a reinforcement learning perspective, exploratory paths that verified intermediate results achieved a higher pass rate on difficult tasks than one-shot guesses. The group-relative advantage mechanism amplified these self-questioning trajectories.&lt;/p&gt;




&lt;h2&gt;
  
  
  V. Hands-on Implementation: A Minimal GRPO Training Pipeline
&lt;/h2&gt;

&lt;p&gt;Using Hugging Face's &lt;strong&gt;TRL (Transformer Reinforcement Learning)&lt;/strong&gt; library, here is an end-to-end runnable script training a lightweight base model (such as &lt;code&gt;Qwen/Qwen2.5-1.5B-Instruct&lt;/code&gt;) with GRPO:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Environment Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;torch transformers trl peft datasets accelerate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Complete Training Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Dataset&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AutoTokenizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AutoModelForCausalLM&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;trl&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GRPOTrainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GRPOConfig&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Prepare deterministic verification dataset
&lt;/span&gt;&lt;span class="n"&gt;train_data&lt;/span&gt; &lt;span class="o"&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;prompt&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;Solve this equation: 3 * x + 7 = 22. What is x? Present your reasoning inside &amp;lt;think&amp;gt; and final value in &amp;lt;answer&amp;gt;.&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;target&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;5&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;prompt&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;A train travels 180 km in 3 hours. What is its speed in km/h? Think first in &amp;lt;think&amp;gt;, give value in &amp;lt;answer&amp;gt;.&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;target&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;60&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;prompt&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;If a square has an area of 64 cm^2, what is its perimeter in cm? Reason in &amp;lt;think&amp;gt;, answer in &amp;lt;answer&amp;gt;.&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;target&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;32&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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;  &lt;span class="c1"&gt;# Expand dataset scale
&lt;/span&gt;
&lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;train_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Define deterministic rule-based reward functions
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;correctness_reward_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompts&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="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Verify if the content in &amp;lt;answer&amp;gt; strictly matches ground truth.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;rewards&lt;/span&gt; &lt;span class="o"&gt;=&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;completion&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;true_target&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;zip&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="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;answer&amp;gt;(.*?)&amp;lt;/answer&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DOTALL&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;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;rewards&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="mf"&gt;2.0&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;true_target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;rewards&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="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rewards&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;format_reward_func&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="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Reward proper reasoning tag encapsulation.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;rewards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^&amp;lt;think&amp;gt;.*?&amp;lt;/think&amp;gt;\s*&amp;lt;answer&amp;gt;.*?&amp;lt;/answer&amp;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;completion&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;completions&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;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DOTALL&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;rewards&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="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;rewards&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="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rewards&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Load model and tokenizer
&lt;/span&gt;&lt;span class="n"&gt;model_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;Qwen/Qwen2.5-1.5B-Instruct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;tokenizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoTokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_id&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;tokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pad_token&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pad_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eos_token&lt;/span&gt;

&lt;span class="c1"&gt;# 4. Configure GRPO Hyperparameters
&lt;/span&gt;&lt;span class="n"&gt;training_args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GRPOConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;output_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./grpo_output_qwen&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;learning_rate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;2e-5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;per_device_train_batch_size&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="n"&gt;gradient_accumulation_steps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;num_generations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;# Group size G=4
&lt;/span&gt;    &lt;span class="n"&gt;max_prompt_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_completion_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Ample space for CoT exploration
&lt;/span&gt;    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;warmup_ratio&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;logging_steps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_steps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;save_strategy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;steps&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;save_steps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;bf16&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;report_to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;none&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 5. Launch the Critic-Free Trainer
&lt;/span&gt;&lt;span class="n"&gt;trainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GRPOTrainer&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="n"&gt;model_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;reward_funcs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;correctness_reward_func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;format_reward_func&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;training_args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;train_dataset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;🚀 Launching critic-free GRPO reinforcement learning pipeline...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;trainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;train&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;For foundational training workflows and adapter memory tuning, review our &lt;a href="https://blog.llmgo.top/en/articles/fine-tuning-guide/" rel="noopener noreferrer"&gt;Comprehensive LLM Fine-Tuning Guide&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  VI. Production Pitfalls: Overthinking and Dynamic Compute Governance
&lt;/h2&gt;

&lt;p&gt;Deploying reasoning models in production requires addressing these operational considerations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Overthinking Trap&lt;/strong&gt;: When asked trivial factual queries ("What is the capital of France?"), models may output 800 tokens of self-questioning, adding seconds of unnecessary Time-To-First-Token (TTFT) latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two-Stage Routing Architecture&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Direct standard conversational requests and retrieval tasks to lightweight models or &lt;a href="https://blog.llmgo.top/en/articles/rag-in-practice/" rel="noopener noreferrer"&gt;RAG retrieval pipelines&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Reserve thinking endpoints for complex logical synthesis, math, and code generation with bounded token limits (&lt;code&gt;max_thinking_tokens&lt;/code&gt;). For high-throughput infrastructure setup, refer to our &lt;a href="https://blog.llmgo.top/en/articles/vllm-serving-guide/" rel="noopener noreferrer"&gt;vLLM Production Serving Guide&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Frequently Asked Questions (FAQ)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Q1: How does GRPO converge reliably without an explicit Critic network?
&lt;/h3&gt;

&lt;p&gt;GRPO replaces the parametric state-value estimation of the Bellman equation with empirical Monte Carlo group sampling. By generating a group of $G$ responses for the same prompt, the group mean serves as a dynamic, unbiased baseline. As long as the group size is sufficient ($G \ge 4 \sim 8$), the normalized advantage $\frac{r_i - \mu}{\sigma}$ accurately signals relative trajectory quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2: Does GRPO eliminate the need for Supervised Fine-Tuning (SFT) data entirely?
&lt;/h3&gt;

&lt;p&gt;While DeepSeek-R1-Zero proved that cold-start reasoning can emerge from pure RL, practical production workflows benefit significantly from a lightweight initial SFT phase. Pure RL on raw base models frequently generates multilingual gibberish, formatting anomalies, and infinite repetition early in training. Starting with a few thousand curated chain-of-thought demonstrations accelerates convergence by over 5x while preserving readability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3: What is the fundamental difference between GRPO and DPO?
&lt;/h3&gt;

&lt;p&gt;DPO (Direct Preference Optimization) is an offline supervised preference algorithm operating on static pairs of chosen and rejected responses $(y_w, y_l)$. It cannot discover novel reasoning pathways absent from the static dataset. GRPO is an active, online reinforcement learning algorithm where the model generates real-time samples evaluated dynamically by verifiable environment rewards, enabling open-ended exploration and spontaneous self-correction.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://blog.llmgo.top/en/articles/test-time-compute-grpo/" rel="noopener noreferrer"&gt;Nobita Talks AI&lt;/a&gt; on blog.llmgo.top.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>reinforcementlearning</category>
      <category>machinelearning</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>AI Coding Mastery: From 'Build Me an X' to Architecture Orchestrator</title>
      <dc:creator>ifnodoraemon</dc:creator>
      <pubDate>Sun, 20 Sep 2026 03:10:37 +0000</pubDate>
      <link>https://dev.to/ifnodoraemon/ai-coding-mastery-from-build-me-an-x-to-architecture-orchestrator-25o5</link>
      <guid>https://dev.to/ifnodoraemon/ai-coding-mastery-from-build-me-an-x-to-architecture-orchestrator-25o5</guid>
      <description>&lt;h2&gt;
  
  
  Preface: You Might Be "Used by AI" Instead of "Using AI"
&lt;/h2&gt;

&lt;p&gt;Have you ever experienced any of these?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You ask AI to build a feature, it delivers 500 lines of code, and after 30 minutes of review you realize it used a framework your project explicitly forbids&lt;/li&gt;
&lt;li&gt;By turn 30 of the conversation, AI starts contradicting itself, overturning decisions it made earlier&lt;/li&gt;
&lt;li&gt;AI's code "looks correct," but crashes in production — because it didn't handle the null edge cases in your business logic&lt;/li&gt;
&lt;li&gt;You switched from Copilot to Cursor hoping for better results, but the same pitfalls persist&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't AI being incompetent, nor is it about picking the wrong tool — &lt;strong&gt;your approach to wielding AI is wrong&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In 2026, AI coding tools have evolved from "Tab completion" to autonomous &lt;a href="https://blog.llmgo.top/en/articles/build-ai-agent/" rel="noopener noreferrer"&gt;Agent systems&lt;/a&gt; capable of planning, executing, and verifying on their own. Claude Code can run your test suites directly; GitHub Copilot Coding Agent auto-creates PRs from Issues; Cline CLI executes commands in sandboxes. Tools are abundant — what's missing is &lt;strong&gt;the methodology to use them correctly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article answers one core question: &lt;strong&gt;How can you make AI reliably and consistently produce production-grade code?&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;Structure:

Part 1: Mindset Shift ——— From Coder to Architecture Orchestrator
Part 2: Six Core Methods — Practical Playbook
Part 3: Five Anti-Patterns — Pitfall Guide
Part 4: Tool Landscape ——— 20+ Tool Selection Matrix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Part 1: Mindset Shift — Your Role Has Changed
&lt;/h2&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph LR
    subgraph Old Model
        A1["You write code"] --&amp;gt; B1["AI autocompletes"]
    end
    subgraph New Model
        A2["You define intent"] --&amp;gt; B2["AI plans"]
        B2 --&amp;gt; C2["AI implements"]
        C2 --&amp;gt; D2["AI verifies"]
        D2 --&amp;gt; E2["You review"]
    end&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;In 2026, a developer's role has shifted from "person who writes code line by line" to &lt;strong&gt;"architect + coach."&lt;/strong&gt; When Andrej Karpathy coined "Vibe Coding" in 2025, saying &lt;em&gt;"I just see things, say things, run things, and copy-paste things,"&lt;/em&gt; many misinterpreted this as "casually let AI write code." The opposite is true — experts spend 70% of their time on &lt;strong&gt;defining constraints, reviewing plans, and encoding lessons learned&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Your core value is no longer writing syntax, but four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Define Intent&lt;/strong&gt; — Clearly describe "what to do" and "what NOT to do," giving AI a quantifiable success criterion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design Constraints&lt;/strong&gt; — Use rule files (&lt;code&gt;AGENTS.md&lt;/code&gt;) and specifications to set boundaries for AI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify Results&lt;/strong&gt; — Use tests, linters, and adversarial reviews to confirm AI output meets architecture standards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encode Lessons&lt;/strong&gt; — After every mistake, encode the fix into rule files so AI permanently learns&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The behavioral gap between experts and beginners is stark:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Beginner Approach&lt;/th&gt;
&lt;th&gt;Expert Approach&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Build me a login system"&lt;/td&gt;
&lt;td&gt;"Don't write code yet. Read the project structure first, then give me an implementation plan"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ask AI to do everything at once&lt;/td&gt;
&lt;td&gt;Break into atomic tasks, verify each before continuing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accept AI's first suggestion&lt;/td&gt;
&lt;td&gt;Ask AI for 2-3 options, analyze trade-offs, then choose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge code they don't understand&lt;/td&gt;
&lt;td&gt;"Explain why this code is written this way"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Re-prompt when AI makes mistakes&lt;/td&gt;
&lt;td&gt;Encode the error into project rule files so AI never repeats it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use one endless chat for everything&lt;/td&gt;
&lt;td&gt;Summarize after each sub-task, start fresh sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Part 2: Six Core Methods
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Method 1: Spec-Driven Development
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Core idea: Make AI understand "what" before it writes code. Changing a plan is always 10x cheaper than changing code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A complete Spec-Driven cycle has four phases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Phase 1: SPECIFY
│  "What to build, what NOT to build, what defines success"
│  → Output: SPEC.md
│
Phase 2: PLAN
│  AI proposes architecture in read-only mode; you review and refine
│  → Output: PLAN.md
│
Phase 3: TASKS
│  Decompose the plan into independently verifiable atomic tasks
│  → Output: TASKS.md
│
Phase 4: IMPLEMENT + VERIFY
   Execute tasks one by one → test → proceed only after passing
   → Output: Working code + tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Practical tips&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Not every task needs a Spec&lt;/strong&gt;. Rule of thumb: if it's cross-session, high-risk, or multi-file, write a Spec; if it's a single function and low-risk, just do it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Plan Mode&lt;/strong&gt;: In Claude Code, say &lt;code&gt;"Don't write code yet, give me a plan"&lt;/code&gt;; in Cursor, describe before starting the Agent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep documents alive&lt;/strong&gt;: Have AI update SPEC.md in real-time during implementation to keep plan and reality in sync&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule of thumb: If you find yourself repeatedly asking AI to "redo," you skipped the SPECIFY and PLAN phases. &lt;strong&gt;Go back to the beginning and align on intent.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Method 2: Context Engineering
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Core idea: "Prompt Engineering" is outdated. The 2026 key skill is "Context Engineering" — not how to ask questions, but how to make the right information automatically appear at the right time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI's output quality is a function of context quality: &lt;code&gt;Output = f(Context)&lt;/code&gt;. What you feed it is what you get back.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Three-Layer Context Architecture
&lt;/h4&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TB
    subgraph Three-Layer Context
        L1["Always-On Layer"] --&amp;gt; |AGENTS.md / .cursorrules| Note1["Minimal base rules, auto-loaded every time"]
        L2["Auto-Attached Layer"] --&amp;gt; |.cursor/rules/*.mdc| Note2["Activated by file path"]
        L3["Session Layer"] --&amp;gt; |"@ references in chat"| Note3["Specific files for current task"]
    end&lt;/code&gt;&lt;/pre&gt;



&lt;h4&gt;
  
  
  Project Rule Files — The "Job Description" for AI
&lt;/h4&gt;

&lt;p&gt;This is the most critical infrastructure for mastering AI. Without it, even the best AI can only give you generic code that may violate project conventions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Tools&lt;/th&gt;
&lt;th&gt;Priority&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AGENTS.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Universal "machine README"&lt;/td&gt;
&lt;td&gt;All platforms (Cursor / Copilot / Claude Code...)&lt;/td&gt;
&lt;td&gt;⭐⭐⭐ Must create&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Claude-specific instructions&lt;/td&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;⭐⭐ Recommended for Claude users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.cursor/rules/*.mdc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Layered rule system&lt;/td&gt;
&lt;td&gt;Cursor&lt;/td&gt;
&lt;td&gt;⭐⭐ Recommended for Cursor users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copilot global instructions&lt;/td&gt;
&lt;td&gt;GitHub Copilot&lt;/td&gt;
&lt;td&gt;⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.goosehints&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Goose instructions&lt;/td&gt;
&lt;td&gt;Goose&lt;/td&gt;
&lt;td&gt;⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What does a good &lt;code&gt;AGENTS.md&lt;/code&gt; look like? Here's an example from my Hugo tech blog:&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="gh"&gt;# Project: ifnodoraemon.github.io (Hugo Tech Blog)&lt;/span&gt;

&lt;span class="gu"&gt;## Tech Stack&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Hugo SSG + Vanilla JS + CSS
&lt;span class="p"&gt;-&lt;/span&gt; Bilingual architecture: content/zh/ and content/en/

&lt;span class="gu"&gt;## Key Commands&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; hugo server -D     # Local preview
&lt;span class="p"&gt;-&lt;/span&gt; npm run build      # Production build

&lt;span class="gu"&gt;## Article Standards&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Chinese articles go in content/zh/articles/{slug}.md
&lt;span class="p"&gt;-&lt;/span&gt; English articles go in content/en/articles/{slug}.en.md
&lt;span class="p"&gt;-&lt;/span&gt; Frontmatter must include: title / slug / date / tag / tagClass / description
&lt;span class="p"&gt;-&lt;/span&gt; tagClass options: tag-blue / tag-green / tag-violet / tag-emerald

&lt;span class="gu"&gt;## Writing Style&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Open with pain-point scenarios, never write "This article will introduce..."
&lt;span class="p"&gt;-&lt;/span&gt; Deep technical analysis + directly copyable code
&lt;span class="p"&gt;-&lt;/span&gt; Use mermaid diagrams and comparison tables

&lt;span class="gu"&gt;## Safety Boundaries&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; ❌ Never modify the public/ directory (build output)
&lt;span class="p"&gt;-&lt;/span&gt; ❌ Don't introduce new CSS frameworks
&lt;span class="p"&gt;-&lt;/span&gt; ❌ Don't modify .github/workflows/ CI configs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: This file is only 25 lines. Brevity is key — every useless instruction dilutes the truly important rules.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Four Golden Rules&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Keep it under 200 lines&lt;/strong&gt; — LLMs suffer from the &lt;a href="https://arxiv.org/abs/2307.03172" rel="noopener noreferrer"&gt;"lost-in-the-middle"&lt;/a&gt; effect: attention to information in the middle of context is lowest. Overly long rules get ignored&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Only write what AI can't infer&lt;/strong&gt; — Don't repeat what linters and type checkers already enforce. "Use TypeScript" is unnecessary; "API routes use kebab-case" is essential&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iterate through friction&lt;/strong&gt; — AI keeps making the same mistake (e.g., always forgetting &lt;code&gt;tagClass&lt;/code&gt; in Hugo frontmatter)? Immediately encode it into the rule file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provide benchmark file paths&lt;/strong&gt; — Instead of lengthy descriptions, "New articles should follow the format in &lt;code&gt;content/zh/articles/mcp-guide.md&lt;/code&gt;" says it all&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cross-tool universality is &lt;code&gt;AGENTS.md&lt;/code&gt;'s killer advantage. Whether you use Cursor, Copilot, Claude Code, or Aider, they all automatically read this file from the project root. Configure once, effective everywhere. For modular domain capabilities and workflow automation, explore our deep dive on &lt;a href="https://blog.llmgo.top/en/articles/skills-guide/" rel="noopener noreferrer"&gt;Skills for AI Coding Assistants&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Method 3: TDD + Agent Verification Loop
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Core idea: Use tests as AI's "brake system." Let tests tell AI if it's right, instead of relying on your eyeball review.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the single most reliable AI coding pattern. Period. The reason is simple — AI excels at "given a quantifiable target, iterate until convergence."&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TD
    A["You write tests: define 'what correct means'"] --&amp;gt; B["AI writes implementation"]
    B --&amp;gt; C{"Run tests"}
    C --&amp;gt;|Pass| D["✅ Next task"]
    C --&amp;gt;|Fail| E["Error logs fed back to AI"]
    E --&amp;gt; F["AI self-corrects"]
    F --&amp;gt; C&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;strong&gt;Why is this the most reliable pattern?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quantifiable success criteria&lt;/strong&gt;: Not "does it look good" (subjective), but "do tests pass" (objective fact)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic guardrails&lt;/strong&gt;: When AI modifies code later, existing tests immediately catch regressions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests are documentation&lt;/strong&gt;: Tests are the best behavioral documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Practical workflow&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You write red tests&lt;/strong&gt; (define expected behavior)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI writes green implementation&lt;/strong&gt; (make tests pass)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI refactors&lt;/strong&gt; (tests stay green)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Real scenario&lt;/strong&gt;: Suppose you want to add an RSS generator to your blog. Don't say "build me an RSS feature" — write tests first:&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;# test_rss.py — You write this
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_rss_contains_latest_articles&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;feed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_rss&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;rss version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;feed&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;articles&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="n"&gt;title&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;feed&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_rss_escapes_html_in_description&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Test&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;script&amp;gt;alert(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;xss&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;feed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_rss&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&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;feed&lt;/span&gt;  &lt;span class="c1"&gt;# Must be escaped
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then tell AI: "Implement the &lt;code&gt;generate_rss&lt;/code&gt; function to make all tests pass." AI receives an &lt;strong&gt;executable specification&lt;/strong&gt;, not a vague natural language description.&lt;/p&gt;

&lt;p&gt;In terminal Agents like Claude Code / Codex CLI / Aider, AI can directly run &lt;code&gt;pytest&lt;/code&gt; and read error output, automatically entering the Red→Green→Refactor cycle until all tests pass.&lt;/p&gt;




&lt;h3&gt;
  
  
  Method 4: Multi-Agent Orchestration (CIV Pattern)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Core idea: Don't let one AI simultaneously be "architect," "coder," and "tester." Separate roles, separate responsibilities.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The CIV (Coordinator-Implementor-Verifier) architecture divides AI workflows into three roles:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TD
    C["Coordinator"] --&amp;gt;|Task decomposition| I1["Implementor A"]
    C --&amp;gt;|Task decomposition| I2["Implementor B"]
    C --&amp;gt;|Task decomposition| I3["Implementor C"]
    I1 --&amp;gt; V["Verifier"]
    I2 --&amp;gt; V
    I3 --&amp;gt; V
    V --&amp;gt;|Pass| D["✅ Merge"]
    V --&amp;gt;|Fail| C&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;You don't need complex frameworks. In daily work, existing tools suffice:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Coordinator&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cursor Chat / Claude Code (Plan Mode)&lt;/td&gt;
&lt;td&gt;Analyze requirements, design solutions, decompose tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Implementor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cursor Agent / Codex CLI / Aider&lt;/td&gt;
&lt;td&gt;Implement tasks one by one per the plan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Verifier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You + test suites + linter&lt;/td&gt;
&lt;td&gt;Review code, run tests, confirm spec compliance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Advanced technique — Adversarial verification&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;After code is written, open a &lt;strong&gt;new AI session&lt;/strong&gt; specifically to find bugs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Assume you are a security auditor. Review the following code for all potential issues:
 1. Security vulnerabilities
 2. Edge cases
 3. Performance bottlenecks
 4. Inconsistencies with project architecture

[paste code]"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This "AI reviewing AI's code" pattern is far more effective than "write and merge."&lt;/p&gt;




&lt;h3&gt;
  
  
  Method 5: Advanced Prompt Techniques
&lt;/h3&gt;

&lt;p&gt;With tools and methodology established, a few key daily interaction techniques significantly boost AI output quality:&lt;/p&gt;

&lt;h4&gt;
  
  
  5.1 Role Definition — RTF Pattern (Role-Task-Format)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❌ Bad: "Write me an API"

✅ Good: "You are a senior Python backend engineer, expert in FastAPI and SQLAlchemy.
      Your task is to add CRUD APIs for the user preferences table.
      Follow the existing Repository Pattern (reference src/api/users.ts).
      Output format: First give a solution overview; I'll confirm before you write code."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference: Role constrains the knowledge domain, Task constrains scope, Format constrains output structure. All three are essential.&lt;/p&gt;

&lt;h4&gt;
  
  
  5.2 Task Chaining — Refuse One-Shot Completion
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❌ Bad: "Build the entire authentication system"

✅ Good:
  Prompt 1: "Analyze the current project's auth dependencies and middleware structure"
  Prompt 2: "Based on the analysis, design a JWT authentication implementation plan"
  Prompt 3: "Implement the auth middleware (**write tests first**)"
  Prompt 4: "Implement the login API (**write tests first**)"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each step can be independently verified, each step has a rollback point.&lt;/p&gt;

&lt;h4&gt;
  
  
  5.3 Plan-First — The Three-Question Method
&lt;/h4&gt;

&lt;p&gt;Before letting AI write code, require it to answer three questions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Don't write code yet. Answer these three questions:
  1. Which files do you plan to modify?
  2. What specifically will you change in each file?
  3. What are the potential risks and edge cases?
  Wait for my confirmation before starting."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5.4 Reflective Correction — Never Say "Try Something Else"
&lt;/h4&gt;

&lt;p&gt;When AI makes a mistake, most people say "That's wrong, try another approach." This is the least effective feedback. The correct way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;① Observe: "The unit test throws JSONDecodeError on line 42"
② Analyze: "It seems you didn't handle the case where input is a JSON string"
③ Instruct: "Please extend the parsing logic to support both dict and JSON string input formats"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The more precise your error feedback, the more accurate the fix. Vague feedback leads to vague fixes.&lt;/p&gt;




&lt;h3&gt;
  
  
  Method 6: Session Hygiene &amp;amp; Context Management
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Core problem: Long sessions → stale information accumulates → AI gets confused → quality cliff-drops&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LLM context windows aren't "bigger is better." Even with &lt;a href="https://blog.llmgo.top/en/articles/ai-trends-2026/" rel="noopener noreferrer"&gt;Gemini 3.1 Pro's 1M token context&lt;/a&gt;, model attention to information in the middle of long contexts remains lowest. More importantly — every turn's history messages consume your effective context space. 30 turns × 2000 tokens average per turn ≈ 60K tokens of historical noise, leaving less and less room for truly important information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution: Session Segmentation&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;Session 1: Analyze requirements → produce SPEC.md → end
Session 2: Design solution based on SPEC.md → produce PLAN.md → end
Session 3: Implement tasks 1-3 based on PLAN.md → commit → end
Session 4: Implement tasks 4-6 based on PLAN.md → commit → end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key principles&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inject essential documents in each new session&lt;/strong&gt;: Have AI read SPEC + PLAN at the start — 2000 tokens of distilled docs can restore full context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Summarize periodically&lt;/strong&gt;: "Summarize what we've done so far and what's remaining," save as a file for the next session's input&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The 30-turn rule&lt;/strong&gt;: Quality likely starts degrading after 30 turns in a single session. Switch to a new one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intermediate artifacts are relay batons&lt;/strong&gt;: SPEC.md → PLAN.md → TASKS.md — each document is "state persistence" between sessions&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 3: Five Anti-Patterns — Pitfall Guide
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Anti-Pattern&lt;/th&gt;
&lt;th&gt;Symptoms&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Kitchen Sink&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dumping 20 files into context, AI gets more confused&lt;/td&gt;
&lt;td&gt;Only provide the 2-3 files the current task needs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;One-Shot Everything&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Build the entire feature," result is mediocre everywhere&lt;/td&gt;
&lt;td&gt;Break into 5-10 atomic tasks, verify each&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No Guardrails&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI introduces forbidden libraries or violates conventions&lt;/td&gt;
&lt;td&gt;Explicitly list prohibitions and benchmark files in &lt;code&gt;AGENTS.md&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Context Rot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;After 30+ turns, AI contradicts itself and forgets decisions&lt;/td&gt;
&lt;td&gt;Segmented sessions + intermediate documents (SPEC/PLAN)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Merge Without Verifying&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI code "looks right," crashes in production on edge cases&lt;/td&gt;
&lt;td&gt;TDD verification loop + adversarial code review&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Why Anti-Pattern 1 happens&lt;/strong&gt;: LLMs aren't databases — the more files you feed it, the less attention each file gets. 200 lines of precise context outperforms 5000 lines of "full dump."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Anti-Pattern 5 is the most dangerous&lt;/strong&gt;: AI-generated code has a "fatal attraction" — it's well-formatted, thoroughly commented, and looks more professional than what you'd write yourself. This "surface polish" lowers your guard, while bugs hide in edge cases you wouldn't think to check (empty arrays, race conditions, timezone issues...).&lt;/p&gt;

&lt;p&gt;If you remember only one rule: &lt;strong&gt;Never merge code you don't understand.&lt;/strong&gt; Even if AI says "this is best practice."&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 4: Tool Landscape Matrix
&lt;/h2&gt;

&lt;p&gt;Methodology first, tools second. &lt;strong&gt;Tools serve methodology, not the other way around.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A key 2026 development is the widespread adoption of &lt;a href="https://blog.llmgo.top/en/articles/mcp-guide/" rel="noopener noreferrer"&gt;MCP (Model Context Protocol)&lt;/a&gt; — the USB-C of AI tools, enabling different AI coding tools to connect to databases, GitHub, file systems, and other external resources through a unified protocol. MCP support has become an important factor in tool selection.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI-Native IDEs — Editors Rebuilt from the Ground Up for AI
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Core Strength&lt;/th&gt;
&lt;th&gt;MCP&lt;/th&gt;
&lt;th&gt;Pricing&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cursor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI-first editor, deep codebase indexing, layered rule system (&lt;code&gt;.cursor/rules/*.mdc&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;$20/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windsurf&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cost-effective, Cascade multi-step task chains&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;$15/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  IDE Extensions — Adding AI to Your Familiar Editor
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Core Strength&lt;/th&gt;
&lt;th&gt;Open Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Broadest ecosystem, Agent Mode + Coding Agent (cloud async) + MCP support&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cline&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pioneer of human-in-the-loop autonomous Agents, rich MCP community&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Roo Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cline fork, role-based execution modes (Architect / Code / Debug)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Continue&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fully open source, supports custom models&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Augment Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enterprise-grade semantic context engine, understands 100K+ file codebases&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Amazon Q Developer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Deep AWS ecosystem awareness (Lambda / CloudFormation / CDK)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gemini Code Assist&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Google Cloud ecosystem integration&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tabnine&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Privacy-first, supports local models and enterprise custom security rules&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Terminal Agents (CLI) — The Fastest-Growing Category of 2025-2026
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Core Strength&lt;/th&gt;
&lt;th&gt;Open Source&lt;/th&gt;
&lt;th&gt;Install&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Claude Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Frontier reasoning capabilities, the go-to for large-scale refactoring&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm i -g @anthropic-ai/claude-code&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cline CLI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rust-built, works with ChatGPT subscription, sandbox execution&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install -g @cline/cli&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gemini CLI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Generous free tier, 1M token context, ReAct loop&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm i -g @google/gemini-cli&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OpenCode&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Model-agnostic (supports 75+ LLMs), TUI interface, privacy-first&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;`curl -fsSL &lt;a href="https://opencode.ai/install" rel="noopener noreferrer"&gt;https://opencode.ai/install&lt;/a&gt; \&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Aider&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Terminal pair-programming pioneer, auto Git commit per edit&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;{% raw %}&lt;code&gt;pip install aider-chat&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Goose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Built by Block, extensible plugin system, autonomous task execution&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Autonomous / Cloud Platform Agents — Issue → PR Fully Automated
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Core Strength&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Copilot Coding Agent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Based on GitHub Actions, auto-analyzes Issues, creates branches, writes code, opens PRs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Devin&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full-stack autonomous Agent, independently completes complex application development&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bolt / Lovable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Natural language → full-stack apps, ideal for rapid prototyping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Augment Intent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-Agent orchestration, "living document" driven parallel development&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Quick Selection Guide — One Line to Tell You What to Use
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fastest start     → GitHub Copilot (broadest ecosystem)
Strongest reasoning → Claude Code (go-to for complex refactoring)
Completely free   → Gemini CLI (1M context + free tier)
Vendor-agnostic   → OpenCode (supports 75+ models)
Git automation    → Aider (auto commit per edit)
VS Code autonomous → Cline / Roo Code
Enterprise monorepos → Augment Code
Async background  → GitHub Copilot Coding Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;2026 best practice: Don't use just one tool.&lt;/strong&gt; Professional developers typically use Cursor/Copilot for daily coding, Claude Code for complex reasoning and large-scale refactoring, Aider for Git integration tasks, and Gemini CLI for ultra-long context analysis. The key isn't which tool you pick — it's unifying them all with the same methodology (Spec → Plan → TDD → Verify).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Complete Mastery Workflow — The Golden Path
&lt;/h2&gt;

&lt;p&gt;Finally, weaving all six methods into a complete workflow:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TD
    A["1. Prepare"] --&amp;gt; B["2. Plan"]
    B --&amp;gt; C["3. Execute"]
    C --&amp;gt; D["4. Verify"]
    D --&amp;gt; E["5. Feedback"]
    E -.-&amp;gt;|"Encode into AGENTS.md"| A

    A -.- A1["AGENTS.md updated&amp;lt;br/&amp;gt;Codebase lints clean"]
    B -.- B1["AI proposes plan → you review&amp;lt;br/&amp;gt;Output: PLAN.md"]
    C -.- C1["Write tests → AI implements&amp;lt;br/&amp;gt;Run tests → git commit"]
    D -.- D1["Full test suite + AI review in new session&amp;lt;br/&amp;gt;Your final review → merge"]
    E -.- E1["Encode issues into rules&amp;lt;br/&amp;gt;Record good patterns as workflows"]&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The essence of this loop is the final step: &lt;strong&gt;the feedback loop&lt;/strong&gt;. Every pitfall strengthens rule files; every success crystallizes into standard procedure. After dozens of iterations, your &lt;code&gt;AGENTS.md&lt;/code&gt; becomes the entire team's "AI user manual" — when a new team member joins, AI immediately knows how to work on your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Takeaways
&lt;/h2&gt;

&lt;p&gt;Remember these four principles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Plan before execute" is a 10x lever&lt;/strong&gt;. Having AI explain its approach before writing code increases success rates by an order of magnitude&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests are the ultimate mastery tool&lt;/strong&gt;. You write tests to define "what correct means," AI's job is to make them pass — this is what AI does best&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rule files are permanent memory&lt;/strong&gt;. Every pitfall encoded into &lt;code&gt;AGENTS.md&lt;/code&gt; makes your AI teammate understand your project better forever&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sessions are disposable&lt;/strong&gt;. Don't fear starting new chats. After 30 turns, switch to a fresh session, inject essential docs, and restart — quality is always better than continuing a stale conversation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One final thought: &lt;strong&gt;The ceiling of AI coding tools isn't model intelligence — it's your methodology for wielding them.&lt;/strong&gt; The six methods and five anti-patterns in this article are your complete roadmap from "being used by AI" to "using AI."&lt;/p&gt;




&lt;h2&gt;
  
  
  Frequently Asked Questions (FAQ)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Q1: How should project-level &lt;code&gt;AGENTS.md&lt;/code&gt; rules coordinate with modular &lt;code&gt;Skills&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;Keep &lt;code&gt;AGENTS.md&lt;/code&gt; lean (under 200 lines) as the global project constitution defining architectural boundaries, styling rules, and critical safety red lines across the whole repository. In contrast, delegate specialized repetitive tasks—such as database migrations, framework-specific refactoring, or CI workflow generation—to dedicated plug-and-play skills. Learn how to construct and package these workflows in our &lt;a href="https://blog.llmgo.top/en/articles/skills-guide/" rel="noopener noreferrer"&gt;Skills Deep Dive: Give Your AI Coding Assistant a Professional Brain&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2: Why does my AI coding assistant struggle to interact with external databases and local services?
&lt;/h3&gt;

&lt;p&gt;Ad-hoc natural language prompts often fail because language models lack standard execution interfaces to developer infrastructure. In 2026, the industry standard is to expose databases, Git repositories, and documentation as standardized servers via the Model Context Protocol. For step-by-step setup guides and tool integration patterns, see our &lt;a href="https://blog.llmgo.top/en/articles/mcp-guide/" rel="noopener noreferrer"&gt;MCP Protocol Guide: From Concept to Production&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3: How do we prevent AI assistants from causing accidental regressions in massive legacy codebases?
&lt;/h3&gt;

&lt;p&gt;Enforce a strict two-stage protocol: mandate a read-only "Plan Mode" where the assistant first generates a &lt;code&gt;PLAN.md&lt;/code&gt; detailing affected files and dependency risks without touching source code. Once you review and approve the plan, execute changes incrementally in isolated sessions verified by deterministic TDD test harnesses, ensuring errors are caught before merging into the main branch.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://blog.llmgo.top/en/articles/ai-coding-mastery/" rel="noopener noreferrer"&gt;Nobita Talks AI&lt;/a&gt; on blog.llmgo.top.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aiengineering</category>
      <category>ai</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
