Files
optimclaw/docs/pdf/lazy-tools.html
T
dingoandClaude Opus 4.6 26b1c5b493 docs: mesh cluster documentation, SVG diagrams, and ironclaw->optimclaw rename
- MESH_CLUSTER.md: full documentation for autonomous AI mesh network
- LAZY_TOOLS.md: lazy tool loading for smaller LLMs
- mesh-architecture.svg: colorful network topology diagram
- task-routing.svg: scoring algorithm visualization
- pq-handshake.svg: ML-KEM-768 key exchange sequence diagram
- HTML docs with dark theme styling
- Renamed ironclaw references to optimclaw in .env.example and README

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-29 13:16:20 +07:00

317 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>OptimClaw - lazy-tools</title>
<style>
/* Default styles provided by pandoc.
** See https://pandoc.org/MANUAL.html#variables-for-html for config info.
*/
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: min(4vw, 1.5em);}
div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
/* The extra [class] is a hack that increases specificity enough to
override a similar rule in reveal.js */
ul.task-list[class]{list-style: none;}
ul.task-list li input[type="checkbox"] {
font-size: inherit;
width: 0.8em;
margin: 0 0.8em 0.2em -1.6em;
vertical-align: middle;
}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
/* CSS for syntax highlighting */
html { -webkit-text-size-adjust: 100%; }
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { color: #008000; } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { color: #008000; font-weight: bold; } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>
<link rel="stylesheet" href="data:text/css,body{font-family:Inter,system-ui,sans-serif;max-width:800px;margin:0 auto;padding:40px;color:%23e0e0e0;background:%231a1a2e}h1,h2,h3{color:%23fab283}code{background:%230f3460;padding:2px 6px;border-radius:3px;color:%2300d4aa}pre{background:%230f3460;padding:16px;border-radius:8px;overflow-x:auto}pre code{background:none}a{color:%235c9cf5}table{border-collapse:collapse;width:100%}th,td{border:1px solid%2330363d;padding:8px;text-align:left}th{background:%230f3460}" />
</head>
<body>
<header id="title-block-header">
<h1 class="title">OptimClaw - lazy-tools</h1>
</header>
<h1 id="optimclaw-lazy-tool-loading">OptimClaw Lazy Tool Loading</h1>
<h2 id="overview">Overview</h2>
<p>Lazy tool loading is an optimization that dramatically reduces the
initial system prompt size sent to the LLM. Instead of injecting full
JSON schemas for every available tool into each request, OptimClaw loads
only a small core set of tools eagerly and defers the rest until the LLM
requests them.</p>
<p><strong>Impact:</strong> System prompt size drops from approximately
13,000 tokens to approximately 4,000 tokens a 70% reduction. This
saves cost on every LLM call and leaves more of the context window
available for conversation history and tool outputs.</p>
<h2 id="how-to-enable">How to Enable</h2>
<p>Set the environment variable:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="bu">export</span> <span class="va">OPTIMCLAW_LAZY_TOOLS</span><span class="op">=</span>1</span></code></pre></div>
<p>Or add it to <code>~/.optimclaw/.env</code>:</p>
<pre class="env"><code>OPTIMCLAW_LAZY_TOOLS=1</code></pre>
<p>To disable (default behavior all tools loaded eagerly):</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="bu">export</span> <span class="va">OPTIMCLAW_LAZY_TOOLS</span><span class="op">=</span>0</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="co"># or simply unset it</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="bu">unset</span> <span class="va">OPTIMCLAW_LAZY_TOOLS</span></span></code></pre></div>
<h2 id="core-tools-always-loaded">Core Tools (Always Loaded)</h2>
<p>When lazy loading is enabled, the following 12 core tools are always
included in the system prompt. These are the tools the LLM needs most
frequently and cover the essential interaction patterns:</p>
<table>
<thead>
<tr>
<th>#</th>
<th>Tool</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td><code>echo</code></td>
<td>Return text to the user</td>
</tr>
<tr>
<td>2</td>
<td><code>time</code></td>
<td>Get current date and time</td>
</tr>
<tr>
<td>3</td>
<td><code>json</code></td>
<td>Parse and query JSON data</td>
</tr>
<tr>
<td>4</td>
<td><code>http</code></td>
<td>Make HTTP requests to allowed endpoints</td>
</tr>
<tr>
<td>5</td>
<td><code>web_fetch</code></td>
<td>Fetch and extract content from web pages</td>
</tr>
<tr>
<td>6</td>
<td><code>file_read</code></td>
<td>Read files from the workspace</td>
</tr>
<tr>
<td>7</td>
<td><code>file_write</code></td>
<td>Write files to the workspace</td>
</tr>
<tr>
<td>8</td>
<td><code>shell</code></td>
<td>Execute shell commands in the sandbox</td>
</tr>
<tr>
<td>9</td>
<td><code>memory_search</code></td>
<td>Search persistent memory (hybrid FTS + vector)</td>
</tr>
<tr>
<td>10</td>
<td><code>memory_write</code></td>
<td>Write to persistent memory</td>
</tr>
<tr>
<td>11</td>
<td><code>message</code></td>
<td>Send messages to channels</td>
</tr>
<tr>
<td>12</td>
<td><code>tool_info</code></td>
<td>Discover and load additional tools on demand</td>
</tr>
</tbody>
</table>
<h2 id="tool-discovery-with-tool_info">Tool Discovery with
tool_info</h2>
<p>The <code>tool_info</code> tool is the mechanism by which the LLM
discovers and loads deferred tools. When the LLM determines it needs a
tool that is not in its current context, it calls <code>tool_info</code>
to retrieve the full schema.</p>
<h3 id="how-it-works">How It Works</h3>
<ol type="1">
<li>The system prompt includes a brief note listing the names of all
available (but not yet loaded) tools.</li>
<li>When the LLM needs one of these tools, it calls
<code>tool_info</code> with the tool name or a search query.</li>
<li><code>tool_info</code> returns the full JSON schema (parameters,
description, examples) for the matched tools.</li>
<li>The LLM can then call the newly loaded tool in subsequent
turns.</li>
</ol>
<h3 id="tool_info-parameters">tool_info Parameters</h3>
<div class="sourceCode" id="cb4"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;name&quot;</span><span class="fu">:</span> <span class="st">&quot;tool_info&quot;</span><span class="fu">,</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;parameters&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;query&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;type&quot;</span><span class="fu">:</span> <span class="st">&quot;string&quot;</span><span class="fu">,</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;description&quot;</span><span class="fu">:</span> <span class="st">&quot;Exact tool name or keyword search query&quot;</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;max_results&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;type&quot;</span><span class="fu">:</span> <span class="st">&quot;number&quot;</span><span class="fu">,</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;description&quot;</span><span class="fu">:</span> <span class="st">&quot;Maximum tools to return (default: 5)&quot;</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h3 id="example-flow">Example Flow</h3>
<p><strong>System prompt includes:</strong> &gt; Additional tools
available (use <code>tool_info</code> to load): <code>job_create</code>,
<code>job_status</code>, <code>job_cancel</code>,
<code>routine_create</code>, <code>routine_list</code>,
<code>skill_search</code>, <code>skill_install</code>,
<code>extension_install</code>, <code>secrets_set</code>,
<code>secrets_get</code>, …</p>
<p><strong>LLM decides it needs to create a background job:</strong></p>
<pre><code>LLM -&gt; tool_info(query=&quot;job_create&quot;)
tool_info returns:
{
&quot;tools&quot;: [{
&quot;name&quot;: &quot;job_create&quot;,
&quot;description&quot;: &quot;Create a new background job with the given prompt and priority&quot;,
&quot;parameters&quot;: {
&quot;prompt&quot;: { &quot;type&quot;: &quot;string&quot;, &quot;required&quot;: true },
&quot;priority&quot;: { &quot;type&quot;: &quot;number&quot;, &quot;default&quot;: 5 },
&quot;timeout_secs&quot;: { &quot;type&quot;: &quot;number&quot;, &quot;default&quot;: 300 }
}
}]
}
LLM -&gt; job_create(prompt=&quot;Summarize today&#39;s news&quot;, priority=3)</code></pre>
<h2 id="when-to-use-lazy-loading">When to Use Lazy Loading</h2>
<table>
<colgroup>
<col style="width: 38%" />
<col style="width: 61%" />
</colgroup>
<thead>
<tr>
<th>Scenario</th>
<th>Recommendation</th>
</tr>
</thead>
<tbody>
<tr>
<td>Production deployment with many tools/MCP servers</td>
<td>Enable significant token savings</td>
</tr>
<tr>
<td>Development and debugging</td>
<td>Disable easier to see all available tools</td>
</tr>
<tr>
<td>Cost-sensitive usage with expensive models</td>
<td>Enable reduces per-request cost</td>
</tr>
<tr>
<td>Clusters with heterogeneous tool sets</td>
<td>Enable each node may have different tools</td>
</tr>
<tr>
<td>Simple setups with few tools (&lt;15 total)</td>
<td>Either minimal difference</td>
</tr>
</tbody>
</table>
<h2 id="performance-characteristics">Performance Characteristics</h2>
<ul>
<li><strong>First request:</strong> Faster, because the system prompt is
smaller and the LLM processes fewer tokens.</li>
<li><strong>Tool discovery round-trip:</strong> When the LLM calls
<code>tool_info</code>, it adds one extra turn before the actual tool
call. In practice this is rare because the 12 core tools handle the
majority of interactions.</li>
<li><strong>Subsequent requests in the same session:</strong> Tool
schemas loaded via <code>tool_info</code> remain in the conversation
context for the duration of the session, so discovery cost is paid at
most once per tool per session.</li>
</ul>
<h2 id="interaction-with-other-features">Interaction with Other
Features</h2>
<ul>
<li><strong>MCP tools:</strong> MCP-connected tool schemas are also
deferred when lazy loading is enabled. They appear in the “additional
tools available” list and are loaded via <code>tool_info</code>.</li>
<li><strong>WASM tools:</strong> Same behavior as MCP tools deferred
and discoverable.</li>
<li><strong>Skills:</strong> Skill tools (<code>skill_list</code>,
<code>skill_search</code>, <code>skill_install</code>,
<code>skill_remove</code>) are deferred. The skill system itself is
unaffected.</li>
<li><strong>Mesh cluster:</strong> Lazy loading is a per-node setting.
Different nodes in a cluster can have different settings.</li>
</ul>
</body>
</html>