<?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: Sopaco</title>
    <description>The latest articles on DEV Community by Sopaco (@sopaco).</description>
    <link>https://dev.to/sopaco</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1662541%2F1942369a-fefc-4b34-9f9f-eedfcf459148.webp</url>
      <title>DEV Community: Sopaco</title>
      <link>https://dev.to/sopaco</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sopaco"/>
    <language>en</language>
    <item>
      <title>Architecture Docs Always Outdated? Let Code "Grow" Them Automatically</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Sat, 05 Sep 2026 07:53:49 +0000</pubDate>
      <link>https://dev.to/sopaco/architecture-docs-always-outdated-let-code-grow-them-automatically-1i12</link>
      <guid>https://dev.to/sopaco/architecture-docs-always-outdated-let-code-grow-them-automatically-1i12</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvun0akng3fdhnhkb0f59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvun0akng3fdhnhkb0f59.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terrain&lt;/strong&gt; — &lt;em&gt;prepares the ground so agents don't have to guess where to stand.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🔗 GitHub: &lt;a href="https://github.com/sopaco/terrain" rel="noopener noreferrer"&gt;https://github.com/sopaco/terrain&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Tech Lead's Pain: Documentation as Technical Debt
&lt;/h2&gt;

&lt;p&gt;As a Tech Lead, you've definitely experienced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architecture docs that took two weeks to write become unrecognizable after one iteration&lt;/li&gt;
&lt;li&gt;Every code review requires explaining "that's not how it's actually designed anymore"&lt;/li&gt;
&lt;li&gt;When newcomers ask "how is this system organized?" you can only answer verbally because the Wiki is long outdated&lt;/li&gt;
&lt;li&gt;When you ask a new AI assistant to explain the system architecture, it can only guess from the code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Once architecture docs drift from code, they become liabilities—worse than having no docs at all.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Terrain's solution: &lt;strong&gt;let documentation emerge from code automatically, instead of being manually written from memory.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Knowledge Factory: Code as the Source of Documentation
&lt;/h2&gt;

&lt;p&gt;Terrain's core is a "knowledge factory"—starting from a Git repository, it auto-generates three layers of documentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Git Code Repository
    │
    ├── scan ──► index.md (Project Index)
    │
    ├── pack ──► repomix.md (Source Index)
    │
    ├── context (LLM) ──► agent/context.md (Agent Macro Architecture Context)
    │
    ├── docs (ACP) ──► human/ (Five C4 Architecture Docs + Mermaid Diagrams)
    │
    └── track ──► freshness.json (Freshness Score)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;em&gt;Five C4 architecture documents auto-generated, covering all levels from containers to code, with Mermaid diagrams.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Can It Stay "Always in Sync"?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Incremental Updates Instead of Full Regeneration
&lt;/h3&gt;

&lt;p&gt;Traditional documentation tools regenerate everything each time. Terrain doesn't:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tracks Git HEAD&lt;/strong&gt; — Precisely knows which files changed since the last scan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Only regenerates changed portions&lt;/strong&gt; — Changes involve a module → update corresponding C4 doc; unrelated modules → reuse existing artifacts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Baseline ledger&lt;/strong&gt; — Records the Git HEAD for each scan; subsequent refreshes do incremental diffs only.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means refreshing knowledge for a large project might take seconds instead of minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Freshness Scoring System
&lt;/h3&gt;

&lt;p&gt;Every knowledge asset carries a &lt;strong&gt;freshness score&lt;/strong&gt;, based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git code change volume vs. documentation's last generation time&lt;/li&gt;
&lt;li&gt;CodeGraph symbol graph drift detection results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the score drops below 50, Agents automatically reduce the weight of that knowledge asset—&lt;strong&gt;ensuring incorrect suggestions are never made based on outdated architectural information.&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;The project list interface clearly displays each project's freshness score. Stale assets are instantly visible.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Dual-Track Output: Human-Readable, AI-Consumable
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Audience&lt;/th&gt;
&lt;th&gt;Document Path&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Human Developers / Tech Leads&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/human/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Narrative C4 docs + Mermaid diagrams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI Coding Assistants&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/agent/context.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Structured architecture overview (≤ 14 KiB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI Source Retrieval&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/agent/repomix.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Repomix source packs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Business Knowledge&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/knowledge/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Glossary and internal conventions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;C4 docs cover four levels: &lt;strong&gt;Container → Component → Code → Dynamic&lt;/strong&gt;, paired with Mermaid diagrams, unfolding layer by layer from macro architecture to micro implementation.&lt;/p&gt;

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




&lt;h2&gt;
  
  
  Source-First Trust Model
&lt;/h2&gt;

&lt;p&gt;When documentation conflicts with code, Terrain follows clear priority:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;repomix source code &amp;gt; CodeGraph symbol graph &amp;gt; context.md &amp;gt; human docs&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This isn't empty talk—repomix packages real source code, CodeGraph indexes real symbol relationships. Architecture docs are just "visual interpretations" of source code. When interpretation conflicts with source, source code is always right.&lt;/p&gt;




&lt;h2&gt;
  
  
  Four-Phase SDD: Making Design Reviewable
&lt;/h2&gt;

&lt;p&gt;Terrain's SDD (Specification-Driven Development) workflow divides development into four phases, each producing reviewable Markdown artifacts:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phase&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;th&gt;Execution Engine&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Requirements Analysis&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1.requirements.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Native LLM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Technical Design&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2.tech-design.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Native LLM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code Generation&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;3.implementation.md&lt;/code&gt; + repo changes&lt;/td&gt;
&lt;td&gt;ACP Agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code Review&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4.code-review.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Native LLM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;SDD four-phase workflow. Each phase produces reviewable Markdown artifacts that Tech Leads can examine step by step.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This means Tech Leads can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Review whether requirements specifications are accurate&lt;/li&gt;
&lt;li&gt;Examine whether technical design is reasonable&lt;/li&gt;
&lt;li&gt;Confirm whether code generation matches the design&lt;/li&gt;
&lt;li&gt;Verify whether code review is thorough&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Every step is documented and traceable. Every step is reviewable.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Initialize a project (auto-generate C4 docs and Agent context)&lt;/span&gt;
terrain init ./my-repo

&lt;span class="c"&gt;# View architecture overview&lt;/span&gt;
terrain project overview &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo

&lt;span class="c"&gt;# Run SDD requirements analysis phase&lt;/span&gt;
terrain sdd run &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo &lt;span class="nt"&gt;--phase&lt;/span&gt; requirements

&lt;span class="c"&gt;# Refresh knowledge (incremental, only update changed parts)&lt;/span&gt;
terrain refresh ./my-repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Who Is This For?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tech Leads&lt;/strong&gt; — Architecture docs never go stale, always in sync with code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architects&lt;/strong&gt; — C4 docs auto-generated from code, eliminating massive maintenance overhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team Managers&lt;/strong&gt; — New member onboarding compressed from days to minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code Reviewers&lt;/strong&gt; — SDD workflow makes every design step traceable and reviewable.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Great architecture isn't written—it grows from code."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>architecture</category>
      <category>documentation</category>
      <category>github</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Knowledge Management in CI/CD: How Terrain Automates Document Updates</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Sat, 05 Sep 2026 07:51:13 +0000</pubDate>
      <link>https://dev.to/sopaco/knowledge-management-in-cicd-how-terrain-automates-document-updates-5426</link>
      <guid>https://dev.to/sopaco/knowledge-management-in-cicd-how-terrain-automates-document-updates-5426</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fugoew2lwfkdtoeryomfp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fugoew2lwfkdtoeryomfp.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terrain&lt;/strong&gt; — &lt;em&gt;prepares the ground so agents don't have to guess where to stand.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🔗 GitHub: &lt;a href="https://github.com/sopaco/terrain" rel="noopener noreferrer"&gt;https://github.com/sopaco/terrain&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Problem in CI/CD Pipelines
&lt;/h2&gt;

&lt;p&gt;Teams often face these issues in CI pipelines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Regenerate documents on every merge&lt;/strong&gt;—but only a few files actually changed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge assets drift from code unnoticed&lt;/strong&gt;—until an AI assistant gives wrong suggestions based on stale information&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every CI environment requires manual toolchain installation&lt;/strong&gt;—CodeGraph, RTK, Skills configured repeatedly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pipeline output is hard to integrate into Agent workflows&lt;/strong&gt;—information needs conversion to Agent-understandable formats&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Terrain's design philosophy is built for automation: JSON output, incremental refresh, headless operation, one-click toolchain deployment.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Capability: CLI-First, JSON Everywhere
&lt;/h2&gt;

&lt;p&gt;All Terrain commands are designed to be callable directly in scripts and pipelines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JSON standard output&lt;/strong&gt; — Every &lt;code&gt;terrain tools&lt;/code&gt; command outputs JSON, no custom format parsing needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NDJSON event streams&lt;/strong&gt; — &lt;code&gt;terrain ask query --stream&lt;/code&gt; outputs line-by-line JSON events for real-time streaming consumption.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headless operation&lt;/strong&gt; — CLI doesn't depend on any display service, runs in pure terminal environments.&lt;/li&gt;
&lt;/ul&gt;

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




&lt;h2&gt;
  
  
  Typical CI Usage: Auto-Refresh Knowledge on Merge
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In CI script: auto-refresh knowledge assets after merge&lt;/span&gt;
terrain refresh &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Output project freshness to logs&lt;/span&gt;
terrain project freshness-cached &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo

&lt;span class="c"&gt;# If freshness is below threshold, mark as warning&lt;/span&gt;
terrain tools freshness &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo | jq &lt;span class="s1"&gt;'.score'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;This means after every code merge, knowledge assets update automatically with no manual intervention.&lt;/strong&gt; New team members who clone the repository see everything up-to-date.&lt;/p&gt;




&lt;h2&gt;
  
  
  Environment Standardization: &lt;code&gt;terrain env apply&lt;/code&gt; One-Click Deploy
&lt;/h2&gt;

&lt;p&gt;In CI or new environments, one command installs all Agent toolchains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Preview components to be installed&lt;/span&gt;
terrain &lt;span class="nb"&gt;env &lt;/span&gt;plan

&lt;span class="c"&gt;# One-click install: Skills, CodeGraph, RTK, AGENTS.md snippets&lt;/span&gt;
terrain &lt;span class="nb"&gt;env &lt;/span&gt;apply

&lt;span class="c"&gt;# Verify installation status&lt;/span&gt;
terrain &lt;span class="nb"&gt;env &lt;/span&gt;status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Skills&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Standardized workflow instructions (knowledge queries, SDD, Ask, architecture analysis)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CodeGraph&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Symbol call graph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RTK&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Compresses shell output, saves tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AGENTS.md&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unified project convention snippets&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;&lt;em&gt;Terrain's environment configuration interface. One click deploys standardized toolchains for all Agents.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Cross-Platform Distribution: npm + Pre-compiled Installers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Installation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;npm package&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CI/CD, headless servers, Agent pipelines&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install -g @terrain-ai/cli&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pre-compiled installer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Local development, desktop use&lt;/td&gt;
&lt;td&gt;Download from GitHub Releases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node.js shim&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tool calls in npm environments&lt;/td&gt;
&lt;td&gt;Auto-installed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;macOS (Apple Silicon)&lt;/strong&gt; and &lt;strong&gt;Windows x64&lt;/strong&gt; both have pre-compiled binaries&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@terrain-ai/cli&lt;/code&gt; and &lt;code&gt;@terrain-ai/rtk&lt;/code&gt; are both installable globally via npm&lt;/li&gt;
&lt;li&gt;Desktop app is packaged via Tauri, includes CLI—no extra installation needed&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Core Technology: Why Is It Pipeline-Friendly?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Native Rust Core, Runs Offline
&lt;/h3&gt;

&lt;p&gt;All core computation is handled by &lt;code&gt;terrain-core&lt;/code&gt; (pure Rust):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No runtime dependencies&lt;/strong&gt; — Single binary, no dependency on Node.js/Python/databases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline execution&lt;/strong&gt; — scan, pack, search, freshness don't call LLMs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic output&lt;/strong&gt; — Same input produces same JSON output, suitable for automated assertions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Incremental Refresh Engine
&lt;/h3&gt;



&lt;pre data-lang="mermaid"&gt;&lt;code&gt;graph TD
    Git[Git Code Repository] --&amp;gt; Scan[ProjectScanner&amp;lt;br/&amp;gt;Collect Git Metadata]
    Scan --&amp;gt; Changed{Which Files Changed?}
    Changed --&amp;gt;|Changed Files| Repack[repomix Repack]
    Changed --&amp;gt;|Changed Modules| Update[Update Corresponding C4 Docs]
    Changed --&amp;gt;|No Changes| Skip[Skip Document Generation]
    Repack --&amp;gt; Context[Update context.md]
    Update --&amp;gt; Score[Recalculate Freshness Score]
    Score --&amp;gt; Output[Output JSON Result]

    style Skip fill:#d4f4e2,stroke:#2a9&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;strong&gt;Only processes what changed&lt;/strong&gt;—this is the core difference between incremental refresh and traditional full regeneration. For a 100K-line project, if only a few files are modified, refresh might take just seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pipeline-Friendly Output Format
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# JSON output can be processed directly by jq/scripts&lt;/span&gt;
terrain tools read-context &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo | jq &lt;span class="s1"&gt;'.modules[].name'&lt;/span&gt;

&lt;span class="c"&gt;# NDJSON stream can be consumed in real-time&lt;/span&gt;
terrain ask query &lt;span class="s2"&gt;"How does the system handle requests?"&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo &lt;span class="nt"&gt;--stream&lt;/span&gt; | &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;line&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$line&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="s1"&gt;'.type'&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# Suitable for CI logs and assertions&lt;/span&gt;
terrain project freshness-cached &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; freshness.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Complete CI Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# .github/workflows/terrain-knowledge.yml&lt;/span&gt;

name: Update Knowledge Assets
on: &lt;span class="o"&gt;[&lt;/span&gt;push, pull_request]

&lt;span class="nb"&gt;jobs&lt;/span&gt;:
  refresh-knowledge:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Terrain CLI
        run: npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @terrain-ai/cli

      - name: Refresh knowledge assets
        run: |
          terrain refresh &lt;span class="nb"&gt;.&lt;/span&gt;
          terrain project freshness-cached &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo

      - name: Check freshness threshold
        run: |
          &lt;span class="nv"&gt;SCORE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;terrain project overview &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo | jq &lt;span class="s1"&gt;'.freshness_score'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SCORE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 50 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
            &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"::warning::Knowledge assets are stale (score: &lt;/span&gt;&lt;span class="nv"&gt;$SCORE&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
          &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Who Is This For?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DevOps Engineers&lt;/strong&gt; — Integrate knowledge asset updates into CI pipelines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform Teams&lt;/strong&gt; — Standardize Agent environments across all projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large-scale Teams&lt;/strong&gt; — New repositories automatically get knowledge assets, no manual configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACP Integrators&lt;/strong&gt; — Connect &lt;code&gt;terrain tools&lt;/code&gt; JSON API to automated Agent loops.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open Source Maintainers&lt;/strong&gt; — Let contributors clone and immediately have full project knowledge.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"JSON output, incremental refresh, one-click deploy—a knowledge pipeline built for automation."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>automation</category>
      <category>cicd</category>
      <category>devops</category>
      <category>documentation</category>
    </item>
    <item>
      <title>Struggling to Onboard New Projects? Terrain Gets You Up to Speed in 5 Minutes</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Sat, 05 Sep 2026 07:49:38 +0000</pubDate>
      <link>https://dev.to/sopaco/struggling-to-onboard-new-projects-terrain-gets-you-up-to-speed-in-5-minutes-1mn2</link>
      <guid>https://dev.to/sopaco/struggling-to-onboard-new-projects-terrain-gets-you-up-to-speed-in-5-minutes-1mn2</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnqxeatlfyh16z207ixok.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnqxeatlfyh16z207ixok.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terrain&lt;/strong&gt; — &lt;em&gt;prepares the ground so agents don't have to guess where to stand.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🔗 GitHub: &lt;a href="https://github.com/sopaco/terrain" rel="noopener noreferrer"&gt;https://github.com/sopaco/terrain&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Pain We All Know
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"Who owns this module? Where's the auth logic? How is the database schema designed?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When inheriting a new project, the traditional answers are: check the Wiki (probably outdated), ask someone on Slack (might have left), or—grep through hundreds of source files blindly.&lt;/p&gt;

&lt;p&gt;Statistics show that &lt;strong&gt;onboarding a new codebase typically takes developers days.&lt;/strong&gt; And if you need an AI coding assistant to understand the project, it can only blindly grep the real-time repository, starting from scratch every time—inefficient and hallucination-prone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terrain compresses those days into minutes.&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;Terrain's project list interface, with each project showing a "freshness score"—instantly assess whether your knowledge is in sync with the code.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Scenario: Register → Initialize → Start Working
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone project → terrain init → get full knowledge assets → start working
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Register the repo&lt;/strong&gt; — Point to a local Git repository; Terrain registers it in the local management table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run initialization&lt;/strong&gt; — Terrain automatically scans code, packages source indexes (repomix), generates C4 architecture docs and Agent context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start working immediately&lt;/strong&gt; — Browse docs in the built-in reader, or ask questions directly via DeepWiki.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;&lt;em&gt;Five auto-generated C4 architecture documents, capturing system structure from multiple levels. Read by humans, consumed by Agents.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What Problems Does It Solve?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Without Terrain&lt;/th&gt;
&lt;th&gt;With Terrain&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Architecture knowledge scattered across Wiki, Slack, and senior engineers' heads&lt;/td&gt;
&lt;td&gt;Engineering knowledge assets auto-generated from actual code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Documentation drifts from code after every refactoring&lt;/td&gt;
&lt;td&gt;Incremental updates + freshness tracking; knowledge flows with Git branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI assistants blindly grep real-time repositories&lt;/td&gt;
&lt;td&gt;Agent reads &lt;code&gt;context.md&lt;/code&gt; first, then targeted source slices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Every team reinvents "how to get AI to understand our repo"&lt;/td&gt;
&lt;td&gt;One-click install of Skills, CodeGraph, RTK, and &lt;code&gt;AGENTS.md&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Core Technology: Why "Always in Sync"?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Incremental Update Mechanism
&lt;/h3&gt;

&lt;p&gt;Terrain doesn't regenerate everything each time. Instead, it &lt;strong&gt;tracks Git HEAD&lt;/strong&gt; and only regenerates what changed since the last scan. This relies on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Git metadata scanning&lt;/strong&gt; — Precisely identifies which files changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freshness scoring system&lt;/strong&gt; — Each asset carries an independent score; below threshold, Agents automatically reduce its weight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Baseline ledger&lt;/strong&gt; — Records the Git HEAD for each scan; subsequent refreshes do incremental diffs only.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Three-Layer Retrieval Architecture
&lt;/h3&gt;

&lt;p&gt;When DeepWiki or &lt;code&gt;terrain tools&lt;/code&gt; receives a question, retrieval happens in three layers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Asset&lt;/th&gt;
&lt;th&gt;Retrieval Method&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Macro&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent/context.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Preloaded, ≤ 14 KiB architecture overview&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Meso&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;human/&lt;/code&gt;, &lt;code&gt;knowledge/&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Full-text search, read on demand&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Micro&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent/repomix.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;grep-pack → read-pack-file for precise location&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When sources conflict, priority is: &lt;strong&gt;repomix source code &amp;gt; CodeGraph &amp;gt; context.md &amp;gt; human docs&lt;/strong&gt;. This ensures Agents always base answers on the most reliable source information.&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;DeepWiki Q&amp;amp;A interface with precise citation sources. Knowledge has freshness guarantees—no more "making things up."&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Native Rust Core: Works Offline
&lt;/h2&gt;

&lt;p&gt;All core computation is handled by &lt;strong&gt;&lt;code&gt;terrain-core&lt;/code&gt; (pure Rust)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single binary, no runtime, no database&lt;/strong&gt; — No dependency on Node.js, Python, or any database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fully offline execution&lt;/strong&gt; — scan/pack/search/freshness don't call LLMs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform pre-compiled binaries&lt;/strong&gt; — Ready-to-use installers for macOS (Apple Silicon) and Windows x64.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LLMs only intervene when generating context documents and DeepWiki Q&amp;amp;A, supporting OpenAI-compatible APIs and Ollama local deployment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install CLI&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @terrain-ai/cli

&lt;span class="c"&gt;# Register and initialize a project&lt;/span&gt;
terrain init ./my-repo

&lt;span class="c"&gt;# Explore project knowledge&lt;/span&gt;
terrain search &lt;span class="s2"&gt;"authentication flow"&lt;/span&gt;
terrain ask query &lt;span class="s2"&gt;"How does the system handle requests?"&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo

&lt;span class="c"&gt;# View project overview and freshness&lt;/span&gt;
terrain project overview &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Who Is This For?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Developers inheriting new projects&lt;/strong&gt; — Say goodbye to blind file searching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team Tech Leads&lt;/strong&gt; — Architecture docs stay close to code, never drift.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anyone needing AI to understand a codebase&lt;/strong&gt; — Give AI a reliable knowledge map instead of letting it grep from scratch.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Terrain paves the way for Agents so they don't have to guess where to stand."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>Your AI Coding Assistant Keeps Guessing Wrong? Terrain Puts It on Solid Ground</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Sat, 05 Sep 2026 07:47:46 +0000</pubDate>
      <link>https://dev.to/sopaco/your-ai-coding-assistant-keeps-guessing-wrong-terrain-puts-it-on-solid-ground-12</link>
      <guid>https://dev.to/sopaco/your-ai-coding-assistant-keeps-guessing-wrong-terrain-puts-it-on-solid-ground-12</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fryt9ru74gel5zlczbdk4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fryt9ru74gel5zlczbdk4.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terrain&lt;/strong&gt; — &lt;em&gt;prepares the ground so agents don't have to guess where to stand.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🔗 GitHub: &lt;a href="https://github.com/sopaco/terrain" rel="noopener noreferrer"&gt;https://github.com/sopaco/terrain&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Sound Familiar?
&lt;/h2&gt;

&lt;p&gt;You inherit a new project and open hundreds of files, blindly searching for architectural information. You ask an AI assistant to help understand the codebase, but it can only grep through the repository in real-time. After every refactoring, the Wiki documentation drifts from reality—and nobody notices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terrain was built to solve exactly these problems.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's an &lt;strong&gt;engineering environment management platform for both human developers and AI coding assistants.&lt;/strong&gt; Point it at a Git repository, and Terrain automatically scans the code, generates architectural documentation, packages source code indexes, and builds a knowledge system—so every user (human or AI) can understand the entire project in minutes instead of days.&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;Above: Terrain's desktop project list interface. Each project displays a freshness score, giving you instant visibility into whether your knowledge is current.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Three Core Pillars
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pillar&lt;/th&gt;
&lt;th&gt;Metaphor&lt;/th&gt;
&lt;th&gt;What You Get&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Knowledge Assets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🗺️ Map&lt;/td&gt;
&lt;td&gt;C4 architecture docs and Agent context auto-generated from code, always in sync&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent Toolchain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🛤️ Road&lt;/td&gt;
&lt;td&gt;CodeGraph, RTK, Terrain CLI—one command to install everything&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Conventions &amp;amp; Workflows&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;📍 Signpost&lt;/td&gt;
&lt;td&gt;Skills, &lt;code&gt;AGENTS.md&lt;/code&gt;, four-phase SDD workflow—keeps AI working by the same rules&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  One Codebase, Two Audiences
&lt;/h2&gt;

&lt;p&gt;Terrain's core philosophy: &lt;strong&gt;the same knowledge serves both humans and AI.&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;Audience&lt;/th&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Human Developers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/human/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Narrative C4 docs with Mermaid diagrams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI Coding Assistants&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/agent/context.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Structured architecture overview (≤ 14 KiB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI Source Retrieval&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/agent/repomix.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Repomix source packs—grep on demand, not preloaded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Business Knowledge&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/knowledge/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Business glossary and internal conventions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;&lt;em&gt;Knowledge Factory: Starting from a Git repository, through scanning, packing, context generation, and documentation output—producing dual-track knowledge assets.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Terrain?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🕐 Minutes-level onboarding&lt;/strong&gt; — Register repo → run init → get full C4 docs and Agent-ready context. Compress days of familiarization into minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔄 Incremental updates&lt;/strong&gt; — Tracks Git HEAD, regenerates only changed portions, not full rebuilds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📊 Freshness scoring&lt;/strong&gt; — Every knowledge asset carries a score. Agents automatically reduce the weight of stale information.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🤝 Unified Agent contract&lt;/strong&gt; — Claude Code, Codex, OpenCode, Cursor all access knowledge through the same &lt;code&gt;terrain tools&lt;/code&gt; interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;⚡ Native Rust performance&lt;/strong&gt; — Single binary, no runtime, no database. scan/pack/search/freshness all run offline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧩 One-click toolchain deployment&lt;/strong&gt; — &lt;code&gt;terrain env apply&lt;/code&gt; installs CodeGraph, RTK, and preset Skills in dependency order.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Architecture at a Glance
&lt;/h2&gt;

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

&lt;p&gt;&lt;strong&gt;Key Architecture Points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;terrain-core&lt;/code&gt; is the domain core—no LLM execution. It handles scanning, packing, searching, freshness scoring, and other pure computation tasks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;terrain-agent&lt;/code&gt; is the execution layer, orchestrating DeepWiki Q&amp;amp;A, knowledge generation, and SDD workflows.&lt;/li&gt;
&lt;li&gt;Lightweight tasks go through native LLM (ADK Runner); heavy tool calls go through ACP subprocesses.&lt;/li&gt;
&lt;li&gt;All Rust types auto-generate TypeScript frontend types via ts-rs, ensuring zero drift in IPC contracts.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Pre-compiled installers (recommended)&lt;/span&gt;
&lt;span class="c"&gt;# Download from GitHub Releases for macOS / Windows&lt;/span&gt;

&lt;span class="c"&gt;# Or install CLI via npm&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @terrain-ai/cli

&lt;span class="c"&gt;# Register and initialize a project&lt;/span&gt;
terrain init ./my-repo

&lt;span class="c"&gt;# Query the knowledge base&lt;/span&gt;
terrain ask query &lt;span class="s2"&gt;"How does the authentication flow work?"&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt; my-repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Community &amp;amp; Ecosystem
&lt;/h2&gt;

&lt;p&gt;Terrain evolved from &lt;a href="https://github.com/sopaco/deepwiki-rs" rel="noopener noreferrer"&gt;Litho/deepwiki-rs&lt;/a&gt; (1.7k★), battle-tested at scale. It extends Litho's documentation capabilities into a full engineering environment platform—adding environment standardization, workflow management, and Agent bridging.&lt;/p&gt;

&lt;p&gt;MIT licensed. Contributions welcome!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Terrain prepares the ground so agents don't have to guess where to stand."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>openwiki</category>
      <category>deepwiki</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>In the Age of AI Coding, What We Lack Isn't a Stronger Model — It's Ground for Agents to Stand On</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Sat, 15 Aug 2026 09:18:40 +0000</pubDate>
      <link>https://dev.to/sopaco/in-the-age-of-ai-coding-what-we-lack-isnt-a-stronger-model-its-ground-for-agents-to-stand-on-kb5</link>
      <guid>https://dev.to/sopaco/in-the-age-of-ai-coding-what-we-lack-isnt-a-stronger-model-its-ground-for-agents-to-stand-on-kb5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;⭐ &lt;strong&gt;Terrain open source&lt;/strong&gt;: &lt;a href="https://github.com/sopaco/terrain" rel="noopener noreferrer"&gt;https://github.com/sopaco/terrain&lt;/a&gt; (MIT License) — a high-performance open-source engineering environment that lays out a "map + roads + trail markers" for AI agents. Star / Issue welcome&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fagciq78p6q971hhe2z5d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fagciq78p6q971hhe2z5d.png" alt=" " width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Over the past two years, we've watched AI coding evolve from "help me write a function" to "take over an entire requirement." Models keep getting smarter and tools keep getting stronger — but one problem has never been solved:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The moment an Agent enters an unfamiliar codebase, it instantly regresses into a "rookie intern."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It doesn't know what your architecture looks like, what your business jargon means, or which conventions it must follow. So it can only blind-grep the repo, read piles of irrelevant files, burn a huge number of tokens, and finally produce a plan that "looks right but is actually a landmine."&lt;/p&gt;

&lt;p&gt;This isn't the model's fault. It's a problem of &lt;strong&gt;terrain&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  A real pain point: Agents running "naked"
&lt;/h2&gt;

&lt;p&gt;Drop any coding agent into your project and this is what it goes through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🕵️ &lt;strong&gt;Blind-man-and-the-elephant exploration&lt;/strong&gt; — greps from scratch, piecing together your architecture by guessing&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Background knowledge only if you feed it&lt;/strong&gt; — business context, module responsibilities, and design constraints have to be written into prompts over and over&lt;/li&gt;
&lt;li&gt;📄 &lt;strong&gt;Docs always one step behind&lt;/strong&gt; — Wiki pages and comments go stale after every refactor, so the agent may be reading the "previous architecture"&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Every team reinvents the wheel&lt;/strong&gt; — there's no standard answer to "how do I onboard AI to our repo"; everyone fends for themselves&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The root problem isn't that "the model isn't smart enough" — it's that "the engineering environment isn't prepared."&lt;/strong&gt;&lt;br&gt;
We ask agents to act precisely on unfamiliar ground, yet we hand them no map at all.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's why &lt;strong&gt;Terrain&lt;/strong&gt; was born. Its core idea fits in one sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Terrain prepares the ground so agents don't have to guess where to stand.&lt;/strong&gt;&lt;br&gt;
— Terrain paves the way so agents don't have to move forward in the dark.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What Terrain is: an "engineering environment," not just another "AI tool"
&lt;/h2&gt;

&lt;p&gt;Terrain is a &lt;strong&gt;standardized, AI-friendly engineering environment management platform&lt;/strong&gt;. Register a Git repo with it, and it automatically turns that repo into a territory where agents can land and work directly.&lt;/p&gt;

&lt;p&gt;Its positioning breaks down into three pillars, which I'll explain with three metaphors:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pillar&lt;/th&gt;
&lt;th&gt;Metaphor&lt;/th&gt;
&lt;th&gt;What you get&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Engineering knowledge assets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🗺️ &lt;strong&gt;Map&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Architecture docs and agent context auto-generated from your code and kept in sync&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Standardized AI environment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🛣️ &lt;strong&gt;Roads&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;A shared "knowledge contract" (Skills, &lt;code&gt;AGENTS.md&lt;/code&gt;, CLI) so every agent reads your project the same way&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Development workflow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🧭 &lt;strong&gt;Trail markers&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;A four-phase standard flow (SDD) from requirements to code review, every step reviewable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Together they form a complete loop: &lt;strong&gt;from code to knowledge, from knowledge to action.&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Three key design decisions you can read off this diagram:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge lives in the repo, not in a cloud database&lt;/strong&gt; — &lt;code&gt;.terrain/&lt;/code&gt; travels with Git branches; every branch carries its own docs; knowledge follows the code;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Humans and agents consume the same knowledge contract&lt;/strong&gt; — the same asset serves both developers and agents, so you never maintain two sources of truth;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heavy lifting goes to external agents&lt;/strong&gt; — Terrain doesn't do the heavy work; it delegates deep tool calls (code generation, etc.) to external coding agents over the ACP protocol.&lt;/li&gt;
&lt;/ol&gt;

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




&lt;h2&gt;
  
  
  Dual-track knowledge: one factory, two languages
&lt;/h2&gt;

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

&lt;p&gt;The most counterintuitive — and most valuable — thing about Terrain is that it treats "docs for humans" and "context for agents" as &lt;strong&gt;two outputs of the same pipeline&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;Audience&lt;/th&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Humans&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/human/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Narrative C4 architecture docs with Mermaid diagrams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/agent/context.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Highly compressed, structured architecture context (≤ 14 KiB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Source index&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/agent/repomix.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;grep-friendly source pack, read on demand, never preloaded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Domain terms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.terrain/knowledge/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Business glossary and team conventions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For developers, this is an &lt;strong&gt;architecture doc that never drifts from the code&lt;/strong&gt;; for agents, it's a &lt;strong&gt;"map" to read the moment they enter the repo&lt;/strong&gt;. One action, two audiences.&lt;/p&gt;




&lt;h2&gt;
  
  
  A little background: not from scratch, but proven practice
&lt;/h2&gt;

&lt;p&gt;Terrain's knowledge engine is a direct descendant of &lt;strong&gt;Litho&lt;/strong&gt; (open-sourced as deepwiki-rs, 1.7k+ stars on GitHub). Litho proved a thesis: &lt;strong&gt;generate architecture docs from code, keep them in sync, and make them agent-ready&lt;/strong&gt; — and it holds up at scale.&lt;/p&gt;

&lt;p&gt;Walking that proven path, Terrain upgrades the idea from "a doc generator" into "a platform":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Incremental updates&lt;/strong&gt; — instead of regenerating everything from scratch, only the changed parts are updated;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broad language support&lt;/strong&gt; — works out of the box with mainstream languages like Rust, TypeScript, Python, Go, Java, and C#;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent-native access&lt;/strong&gt; — via the ACP protocol, Claude Code, Codex, OpenCode, Cursor — and even the red-hot DeepSeek Harness (DSH) — can all read the same knowledge directly;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment standardization&lt;/strong&gt; — one command deploys Skills, the CLI toolchain, and &lt;code&gt;AGENTS.md&lt;/code&gt;; no per-repo manual setup.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you liked Litho's documentation capabilities, Terrain is Litho's knowledge core &lt;strong&gt;plus&lt;/strong&gt; the environment, workflow, and agent bridge built around it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Who is Terrain for?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🧑💻 &lt;strong&gt;Developers&lt;/strong&gt; — want to understand an unfamiliar codebase in seconds, or give their own project a "living" architecture doc&lt;/li&gt;
&lt;li&gt;🧑🔧 &lt;strong&gt;Tech leads&lt;/strong&gt; — want an architecture doc that tracks code evolution instead of a stale draft rotting in a Wiki&lt;/li&gt;
&lt;li&gt;👥 &lt;strong&gt;Teams adopting AI coding&lt;/strong&gt; — need a shared knowledge contract so every agent understands the project consistently&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;CI/CD teams&lt;/strong&gt; — regenerate knowledge assets on every merge, so the docs never fall behind&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How easy is it to get started?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Use the &lt;strong&gt;GUI&lt;/strong&gt; (for everyone — one-click configuration, fully integrated features)&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Use the &lt;strong&gt;CLI&lt;/strong&gt; (for professional developers and CI/CD scenarios)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Register your repo&lt;/span&gt;
terrain init

&lt;span class="c"&gt;# Generate knowledge assets + deploy the agent toolchain in one go&lt;/span&gt;
terrain assets
terrain &lt;span class="nb"&gt;env &lt;/span&gt;apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or just launch the desktop app and do scanning, reading, Q&amp;amp;A, and environment setup from the GUI. &lt;strong&gt;From registration to a full knowledge base: minutes, not days.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;The next bottleneck of AI coding is probably not "can the model write code" — it's &lt;strong&gt;"can the agent understand your project."&lt;/strong&gt; Once the engineering environment is prepared — map, roads, and trail markers all in place — agents can evolve from "able to write code" to "able to write good code."&lt;/p&gt;

&lt;p&gt;Terrain wants to be exactly that ground where agents can stand.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🚀 &lt;strong&gt;Open source&lt;/strong&gt;: github.com/sopaco/terrain (MIT License)&lt;br&gt;
⭐ If you believe "paving the ground for agents" is worth it, give us a Star.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;If you're interested in topics like "how to keep knowledge assets fresh" or "how to let multiple agents share one understanding," there's more in this series.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Hermes Agent Codebase Packing Tool Usage Guide (repomix-rs High-Performance Edition)</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Mon, 22 Jun 2026 01:59:35 +0000</pubDate>
      <link>https://dev.to/sopaco/hermes-agent-codebase-packing-tool-usage-guide-repomix-rs-high-performance-edition-3hko</link>
      <guid>https://dev.to/sopaco/hermes-agent-codebase-packing-tool-usage-guide-repomix-rs-high-performance-edition-3hko</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This is the official recommended usage guide for repomix-rs&lt;/strong&gt; — repomix-rs is a high-performance Rust rewriting of the original Repomix (TypeScript), fully compatible with the original usage pattern, and Faster, Safer, and better suited for AI Agent scenarios.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What is repomix-rs?
&lt;/h2&gt;

&lt;p&gt;repomix-rs is a tool that packages an entire codebase into a single, AI-friendly file. It works seamlessly with all major LLM application scenarios including Hermes Agent, Claude, ChatGPT, and Gemini. Through repomix-rs, your codebase is presented to AI in a structured, token-controllable format, enabling AI to perform code reviews, documentation generation, and vulnerability audits more accurately.&lt;/p&gt;

&lt;p&gt;Compared to the original Repomix, repomix-rs rewrites all core logic in Rust, bringing a qualitative leap in performance, security, and embedding capabilities.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;repomix-rs (Rust)&lt;/th&gt;
&lt;th&gt;Original Repomix (TypeScript)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Core Language&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime Speed&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Millisecond-level&lt;/strong&gt; (parallel file scanning)&lt;/td&gt;
&lt;td&gt;Second-level (single-threaded Node.js)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory Safety&lt;/td&gt;
&lt;td&gt;Compile-time guaranteed&lt;/td&gt;
&lt;td&gt;Runtime checking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built-in MCP Support&lt;/td&gt;
&lt;td&gt;✅ Official MCP Server included&lt;/td&gt;
&lt;td&gt;❌ Additional configuration required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secretlint Integration&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tree-sitter&lt;/td&gt;
&lt;td&gt;✅ 10 languages&lt;/td&gt;
&lt;td&gt;✅ 10 languages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Token Counting&lt;/td&gt;
&lt;td&gt;tiktoken-rs (&lt;code&gt;o200k_base&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;tiktoken (JS)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remote Repository Packing&lt;/td&gt;
&lt;td&gt;✅ git clone + cleanup&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parallel Processing&lt;/td&gt;
&lt;td&gt;rayon + tokio&lt;/td&gt;
&lt;td&gt;No parallelism&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🦀 Rust: The Infrastructure Choice for the AI Era
&lt;/h2&gt;

&lt;p&gt;Have you noticed a trend? &lt;strong&gt;More and more developer ecosystem infrastructure is moving from TypeScript/Node.js to Rust.&lt;/strong&gt; This is no accident — Rust's language characteristics are a perfect match for the demands of the AI era:&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Why are developers choosing Rust?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Compile-time performance assurance&lt;/strong&gt; — Zero-cost abstractions + no GC pauses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory safety&lt;/strong&gt; — Compile-time elimination of BufferOverflow / Use-After-Free&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform single binary&lt;/strong&gt; — Compile once, run anywhere&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The core choice for the MCP era&lt;/strong&gt; — The AI Agent ecosystem is forming a new technical standard&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  🌟 Rust Replacement Cases: From Bun to Vite
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Bun Case: The Rust Replacement for Node.js
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://blog.csdn.net/weixin_45541665/article/details/161105498" rel="noopener noreferrer"&gt;Rust-based high-performance runtime Bun&lt;/a&gt; uses Rust to rewrite the JavaScript engine, delivering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Startup speed: Node.js ~2s → Bun ~0.1s&lt;/li&gt;
&lt;li&gt;Execution speed: JavaScript ~2x → Bun ~5-10x&lt;/li&gt;
&lt;li&gt;Memory footprint: Node.js ~600MB → Bun ~200-500MB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bun's success proves the &lt;strong&gt;feasibility of Rust as a JS engine底层&lt;/strong&gt;, and repomix-rs leverages Rust's high-performance characteristics to achieve a repomix rewrite.&lt;/p&gt;

&lt;h4&gt;
  
  
  Vite Case: Rust Rewriting of Frontend Build
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://zhuanlan.zhihu.com/p/2017213814882463972" rel="noopener noreferrer"&gt;How Vite ditched Webpack and used Rust to refactor frontend builds&lt;/a&gt; Webpack was the ruler of frontend builds, but it suffered from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slow startup: 5-30s&lt;/li&gt;
&lt;li&gt;Memory usage: 500-2000MB&lt;/li&gt;
&lt;li&gt;Node.js single-thread bottleneck&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Vue.js team decided to ditch Webpack and rewrite Vite in Rust:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Startup speed: 5-30s → ~0.5s&lt;/li&gt;
&lt;li&gt;Memory usage: 500-2000MB → ~200MB&lt;/li&gt;
&lt;li&gt;Concurrent processing: Event loop → Multi-threaded&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vite's success proves that &lt;strong&gt;Rust is the core choice for the next generation of frontend build engines&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Start: No Installation Required, Just Run
&lt;/h2&gt;

&lt;p&gt;Open your terminal, navigate to the project root directory, and execute any of the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Method 1: Run with npx (no global installation needed)&lt;/span&gt;
npx repomix-rs &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Method 2: Install globally then run directly&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; repomix-rs
repomix &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# After the terminal outputs a result, send it to Hermes with: "Please read this first"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After execution, an output file (default &lt;code&gt;repomix-output.xml&lt;/code&gt;) will be generated in the current directory. Drag that file into the Hermes Agent chat window and send the message: &lt;strong&gt;"Please read this project structure file first"&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Why repomix-rs?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In AI Agent scenarios like Hermes Agent, we recommend the Rust version repomix-rs over the TypeScript original:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smaller image size&lt;/strong&gt;: Rust binary ~15MB vs Node.js runtime 50+MB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster startup&lt;/strong&gt;: Rust ~0.05s vs Node.js ~200ms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smaller memory footprint&lt;/strong&gt;: Rust ~50MB vs Node.js ~150MB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better native MCP support&lt;/strong&gt;: repomix-rs includes a built-in MCP Server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This is a technology choice problem&lt;/strong&gt; — The success of Bun and Vite has already proven:&lt;br&gt;
&lt;strong&gt;In the AI era, Rust is the better infrastructure choice&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Remote Repository Direct Packing
&lt;/h2&gt;

&lt;p&gt;No cloning required — one command to pack a remote GitHub repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx repomix-rs &lt;span class="nt"&gt;--remote&lt;/span&gt; https://github.com/username/project-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specify a branch (safer):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx repomix-rs &lt;span class="nt"&gt;--remote&lt;/span&gt; https://github.com/username/project-name &lt;span class="nt"&gt;--branch&lt;/span&gt; main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;repomix-rs's remote packing is based on the system &lt;code&gt;git&lt;/code&gt; command. The first run pulls the full repository snapshot.&lt;br&gt;
If git is unavailable, this step is skipped with a warning and the main process continues uninterrupted.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Fine-Grained Control: Which Files to Include, Which to Exclude
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;.repomixrc&lt;/code&gt; configuration file:&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;"include"&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="s2"&gt;"src/**/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tests/**/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pyproject.toml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"README.md"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exclude"&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="s2"&gt;"**/*.log"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"**/dist/**"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"**/.git/**"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node_modules/**"&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;Enable compression (extracts function signatures, compression ratio up to 50%-90%):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx repomix-rs &lt;span class="nt"&gt;--compress&lt;/span&gt; &lt;span class="nt"&gt;--remove-comments&lt;/span&gt; &lt;span class="nt"&gt;--remove-empty-lines&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Include only specific language files and ignore test directories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx repomix-rs &lt;span class="nt"&gt;--include&lt;/span&gt; &lt;span class="s2"&gt;"*.rs,*.toml,Cargo.*"&lt;/span&gt; &lt;span class="nt"&gt;--ignore&lt;/span&gt; &lt;span class="s2"&gt;"target/**,tests/**"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Output Format Selection
&lt;/h2&gt;

&lt;p&gt;repomix-rs supports four output formats, switchable via the &lt;code&gt;--style&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;npx repomix-rs &lt;span class="nt"&gt;--style&lt;/span&gt; markdown &lt;span class="nt"&gt;--output&lt;/span&gt; output.md &lt;span class="nb"&gt;.&lt;/span&gt;
npx repomix-rs &lt;span class="nt"&gt;--style&lt;/span&gt; json &lt;span class="nt"&gt;--output&lt;/span&gt; output.json &lt;span class="nb"&gt;.&lt;/span&gt;
npx repomix-rs &lt;span class="nt"&gt;--style&lt;/span&gt; plain &lt;span class="nt"&gt;--output&lt;/span&gt; output.txt &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How to Connect to Hermes Agent (Critical Steps)
&lt;/h2&gt;

&lt;p&gt;Hermes Agent does not automatically scan attachment content — it must be triggered manually. The correct process is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;npx repomix-rs .&lt;/code&gt; to generate the packed file&lt;/li&gt;
&lt;li&gt;Drag &lt;code&gt;repomix-output.xml&lt;/code&gt; (or &lt;code&gt;.md&lt;/code&gt; / &lt;code&gt;.txt&lt;/code&gt;) into the Hermes Agent chat window&lt;/li&gt;
&lt;li&gt;Send the prompt: &lt;strong&gt;"Please read this project structure file first"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Wait for Hermes to reply "Context loaded" before asking specific questions&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Hermes only supports &lt;code&gt;.md&lt;/code&gt; / &lt;code&gt;.xml&lt;/code&gt; / &lt;code&gt;.txt&lt;/code&gt; plain text files.&lt;br&gt;
If you accidentally send a compressed archive or binary file, the AI side will not be able to parse it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Running as an MCP Server (Recommended for Advanced Users)
&lt;/h2&gt;

&lt;p&gt;repomix-rs includes a built-in MCP Server that can be directly embedded into any AI Agent supporting the Model Context Protocol (including Hermes Agent, Cursor, and Claude Desktop):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;repomix &lt;span class="nt"&gt;--mcp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After startup, the following MCP tools are exposed:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool Name&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;code&gt;pack_codebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pack a local codebase directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pack_remote_repository&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fetch and pack a remote Git repository&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;read_repomix_output&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read a previously generated repomix output file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;grep_repomix_output&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Search content within the output file&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Cursor / Claude Desktop Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Claude Desktop (macOS)
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&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;"mcpServers"&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;"repomix"&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;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"repomix"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&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="s2"&gt;"--mcp"&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;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;
  
  
  Cursor
&lt;/h3&gt;

&lt;p&gt;Go to Settings → MCP → Add new global MCP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Command: repomix
Args: &lt;span class="nt"&gt;--mcp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Performance Comparison: Original vs repomix-rs
&lt;/h2&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;Original Repomix (Node.js)&lt;/th&gt;
&lt;th&gt;repomix-rs (Rust)&lt;/th&gt;
&lt;th&gt;Speedup&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Small-to-medium projects (&amp;lt; 500 files)&lt;/td&gt;
&lt;td&gt;~3-8 seconds&lt;/td&gt;
&lt;td&gt;~0.3-0.8 seconds&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5-10×&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium projects (500-5,000 files)&lt;/td&gt;
&lt;td&gt;~30-120 seconds&lt;/td&gt;
&lt;td&gt;~2-8 seconds&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;15-40×&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large projects (5,000+ files)&lt;/td&gt;
&lt;td&gt;Risk of OOM&lt;/td&gt;
&lt;td&gt;Stable completion&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Unbounded&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remote repository packing&lt;/td&gt;
&lt;td&gt;Slow (Node.js clone)&lt;/td&gt;
&lt;td&gt;Extremely fast (git + rayon)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;10-20×&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Why repomix-rs Instead of the Original Repomix?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Unmatched speed&lt;/strong&gt; — Rust zero-cost abstractions + rayon parallelism + tokio async I/O; packing the same repository takes only 1/10th the time of the original, or even less.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native MCP Support&lt;/strong&gt; — One command &lt;code&gt;repomix --mcp&lt;/code&gt; directly integrates with Hermes, Claude, Cursor, and more with no additional wrapper layer needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safer dependency tree&lt;/strong&gt; — Rust binaries require no Node.js runtime; simple deployment, low CVE risk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fully compatible with original CLI&lt;/strong&gt; — Parameter names, config file formats, and output formats are nearly identical; zero learning curve when switching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More accurate token counting&lt;/strong&gt; — &lt;code&gt;tiktoken-rs&lt;/code&gt; uses OpenAI's official &lt;code&gt;o200k_base&lt;/code&gt; encoding, consistent with GPT-4o, with far less counting bias than the JS version.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q: What's the difference between &lt;code&gt;npx repomix-rs&lt;/code&gt; and &lt;code&gt;npx repomix&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A: &lt;code&gt;npx repomix-rs&lt;/code&gt; invokes repomix-rs (Rust implementation), which is faster and more stable; &lt;code&gt;npx repomix&lt;/code&gt; invokes the original TypeScript implementation. Their command-line parameters are largely compatible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Can repomix-rs handle my Node.js project?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A: Absolutely — it is language-agnostic. repomix-rs identifies file types through file extensions and glob rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: How do I verify that exclude rules are working?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A: After generating the output, run a grep check: &lt;code&gt;grep -i "secrets\|password\|API_KEY" repomix-output.xml&lt;/code&gt;. If sensitive words appear, check whether your glob rules are correct (e.g., &lt;code&gt;**/.env&lt;/code&gt;, not &lt;code&gt;.env&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Does repomix-rs support Windows?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A: Yes, Windows x64 precompiled binaries have been released. The npm package also covers Linux/macOS/Windows.&lt;/p&gt;




&lt;h2&gt;
  
  
  📢 Quick Start with repomix-rs
&lt;/h2&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/sopaco/repomix-rs" rel="noopener noreferrer"&gt;https://github.com/sopaco/repomix-rs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This guide is adapted from the original Hermes Agent Repomix usage guide, with all content migrated to repomix-rs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;repomix-rs project: &lt;a href="https://github.com/sopaco/repomix-rs" rel="noopener noreferrer"&gt;https://github.com/sopaco/repomix-rs&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;npm package name: &lt;code&gt;repomix-rs&lt;/code&gt;, CLI command: &lt;code&gt;repomix&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>rust</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>repomix-rs: A Deep Dive into AI Code Context Infrastructure Built with Rus</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Mon, 22 Jun 2026 01:26:35 +0000</pubDate>
      <link>https://dev.to/sopaco/repomix-rs-a-deep-dive-into-ai-code-context-infrastructure-built-with-rus-4nkm</link>
      <guid>https://dev.to/sopaco/repomix-rs-a-deep-dive-into-ai-code-context-infrastructure-built-with-rus-4nkm</guid>
      <description>&lt;h1&gt;
  
  
  Architecture Perspective — Examining repomix-rs's Design Philosophy, Crate Architecture, Data Lifecycle, and Relationship with the AI Agent Ecosystem from an Engineering Height
&lt;/h1&gt;

&lt;p&gt;This document is aimed at senior engineers, architects, and technical decision-makers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why Do We Need Code Context Infrastructure?&lt;/li&gt;
&lt;li&gt;repomix-rs Architecture Overview&lt;/li&gt;
&lt;li&gt;Crate Architecture Deep Dive&lt;/li&gt;
&lt;li&gt;Data Lifecycle: From Disk to AI Context&lt;/li&gt;
&lt;li&gt;Core Design Decisions and Trade-offs&lt;/li&gt;
&lt;li&gt;The Philosophy of Configuration: Layered Overrides and the Principle of Least Surprise&lt;/li&gt;
&lt;li&gt;MCP: Turning Tools into AI-Native Capabilities&lt;/li&gt;
&lt;li&gt;The Source of Performance: A Rust Architect's Perspective&lt;/li&gt;
&lt;li&gt;Security Architecture: A Multi-Layer Defense System&lt;/li&gt;
&lt;li&gt;Relationship with Mainstream AI Toolchains&lt;/li&gt;
&lt;li&gt;Project Roadmap and Ecosystem Position&lt;/li&gt;
&lt;/ol&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Open source, feel free to give a star 💎 GitHub 🫱&lt;/strong&gt;: &lt;a href="https://github.com/sopaco/repomix-rs" rel="noopener noreferrer"&gt;https://github.com/sopaco/repomix-rs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  1. Why Do We Need Code Context Infrastructure?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The LLM "Context Window Anxiety"
&lt;/h3&gt;

&lt;p&gt;Although current mainstream LLMs (Deepseek, GLM) have expanded their context windows, token costs grow linearly. A medium-sized project's complete source code often exceeds 100K tokens, surpassing the comfortable processing range of most models. Traditional solutions have structural flaws:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Manual splitting + prompt engineering&lt;/td&gt;
&lt;td&gt;High human cost, not scalable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAG (vector retrieval)&lt;/td&gt;
&lt;td&gt;Loses global structure; depends on embedding quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy-paste into chat&lt;/td&gt;
&lt;td&gt;Error-prone; cannot be automated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;git archive + compression&lt;/td&gt;
&lt;td&gt;AI cannot directly consume it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;repomix solves a more fundamental problem: how to transmit a codebase's structure and content in an AI-readable format, precisely, completely, and reproducibly.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Token Economy
&lt;/h3&gt;

&lt;p&gt;The core constraint of AI engineering is the token budget. repomix-rs addresses three problems in a targeted way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Precise billing&lt;/strong&gt; — Uses &lt;code&gt;tiktoken-rs&lt;/code&gt; (OpenAI &lt;code&gt;o200k_base&lt;/code&gt;), fully aligned with GPT-4o billing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Budget control&lt;/strong&gt; — &lt;code&gt;--split-output&lt;/code&gt; allows splitting by tokens, ensuring the context window is never exceeded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Budget optimization&lt;/strong&gt; — &lt;code&gt;--compress&lt;/code&gt; (Tree-sitter) saves an average of 70% tokens without losing structural information.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  2. repomix-rs Architecture Overview
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────────────────┐
│                         AI Consumer Layer                                   │
│  ┌──────────────┐   ┌──────────────┐   ┌──────────────────────────────────┐ │
│  │  Claude      │   │  Cursor      │   │  Hermes Agent                    │ │
│  │  Desktop     │   │  IDE         │   │  Custom Agents                   │ │
│  └──────┬───────┘   └──────┬───────┘   └──────────────┬───────────────────┘ │
│         └──────────┼──────────┼──────────────────────┼────────────────────┘ │
│              MCP Protocol (JSON-RPC over stdio)                             │
│                              ▼                                             │
│  ┌────────────────────────────────────────────────────────────────────────┐ │
│  │  repomix-mcp (MCP Server)                                              │ │
│  │  Tools: pack_codebase | pack_remote_repository                         │ │
│  │         read_repomix_output | grep_repomix_output                      │ │
│  └────────────────────────────────┬───────────────────────────────────────┘ │
│                                     │                                       │
│       ┌─────────────┐ ┌────────────┴────────────────────┐                  │
│       │repomix-cli │ │          repomix-core           │                  │
│       │(clap CLI)  │ │         (Library)               │                  │
│       └──────┬──────┘ └──────────┬──────────────────────┘                  │
│              │                   │  repomix-config                          │
│              └───────────────────┤ (Config Schema)                          │
│                                  │                                          │
│  ┌─────────────┐ ┌────────────┐ ┌─────────────┐                             │
│  │File Collector│ │ Processor  │ │ Git Intg.   │                             │
│  │(rayon par.) │ │(tree-sitter)│ │ (git CLI)   │                             │
│  └──────┬────────┘ └─────┬──────┘ └──────┬──────┘                             │
│  ┌────────┴────────────────┼──────────────┼────────────────┐                │
│  │                         ▼              ▼                ▼                │
│  │  ┌──────────┐  ┌────────────────┐  ┌──────────────┐                     │
│  │  │File System│ │ Secretlint     │  │ tiktoken-rs  │                     │
│  │  │(tokio fs) │ │ (Security)     │  │ (Tokenize)   │                     │
│  │  └──────────┘  └────────────────┘  └──────────────┘                     │
└─────────────────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Crate Architecture Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Cargo Workspace Design
&lt;/h3&gt;

&lt;p&gt;repomix-rs adopts a &lt;strong&gt;5-Crate Cargo Workspace&lt;/strong&gt; architecture, aligned with Rust ecosystem best practices for layered design:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;repomix-rs/
├── crates/
│   ├── repomix-core/    ← Core engine (public API)
│   ├── repomix-config/  ← Config types + default modes
│   ├── repomix-shared/  ← Cross-crate shared types
│   ├── repomix-cli/     ← CLI entry point (depends on core + config)
│   └── repomix-mcp/     ← MCP Server (depends on core + shared)
├── Cargo.toml            ← workspace root
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Individual Crate Responsibilities
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;repomix-core&lt;/code&gt; (Core Engine)
&lt;/h4&gt;

&lt;p&gt;This is the sole "business logic" crate, encompassing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Module&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;code&gt;file_collector&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Recursive directory scanning; apply include/exclude rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;processor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File content processing (compression, comment removal, AST analysis)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;output&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Serialization for four formats (XML / MD / JSON / Plain)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Git-aware operations (change frequency analysis, diff, log)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;metrics&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Token counts, character statistics, Top-N leaderboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;security&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Secretlint integration; suspicious file detection&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Exposed Traits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[async_trait]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;ProgressCallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Sync&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;on_progress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;fn&lt;/span&gt; &lt;span class="nf"&gt;on_complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;fn&lt;/span&gt; &lt;span class="nf"&gt;on_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;FileProcessor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Sync&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;fn&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ProcessedFile&lt;/span&gt;&lt;span class="o"&gt;&amp;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;h4&gt;
  
  
  &lt;code&gt;repomix-config&lt;/code&gt; (Configuration Schema)
&lt;/h4&gt;

&lt;p&gt;Dedicated to type-safe configuration and default values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;RepomixConfig&lt;/code&gt;: Root config struct, derives &lt;code&gt;Deserialize&lt;/code&gt;/&lt;code&gt;Serialize&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;OutputConfig&lt;/code&gt;: Output format, path, compression options&lt;/li&gt;
&lt;li&gt;Default ignore patterns: &lt;code&gt;node_modules/&lt;/code&gt;, &lt;code&gt;__pycache__/&lt;/code&gt;, &lt;code&gt;.git/&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;Global config path resolution: &lt;code&gt;~/.repomix/repomix.config.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;repomix-shared&lt;/code&gt; (Cross-Crate Shared Types)
&lt;/h4&gt;

&lt;p&gt;Holds type definitions shared across crates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ProcessedFile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PathBuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;is_suspicious&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;compress_ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;PackResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;total_files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;total_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;total_characters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;top_files_by_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FileTokenCount&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;suspicious_files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SuspiciousFileResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;skipped_files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SkippedFile&lt;/span&gt;&lt;span class="o"&gt;&amp;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;h4&gt;
  
  
  &lt;code&gt;repomix-cli&lt;/code&gt; (CLI Layer)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Uses &lt;code&gt;clap&lt;/code&gt; (derive mode) for argument parsing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;#[tokio::main]&lt;/code&gt; async main&lt;/li&gt;
&lt;li&gt;Advanced output formatting (progress bars, colors, JSON machine-readable output)&lt;/li&gt;
&lt;li&gt;Contains no business logic&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;repomix-mcp&lt;/code&gt; (MCP Server Layer)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Uses &lt;code&gt;rmcp&lt;/code&gt; crate (Rust MCP SDK)&lt;/li&gt;
&lt;li&gt;JSON-RPC over stdio&lt;/li&gt;
&lt;li&gt;Internal concurrency isolation via &lt;code&gt;tokio::Mutex&lt;/code&gt; (prevents concurrent git clone conflicts)&lt;/li&gt;
&lt;li&gt;Exposes 4 tools, each with a &lt;code&gt;serde&lt;/code&gt;-structured parameter schema&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.3 Layered Dependency Diagram
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;repomix-mcp ─────────────► repomix-core
     ▲                        │
     │                        │
repomix-cli ────────────────┤
                             │
                      repomix-config
                             ▲
                             │
                      repomix-shared
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No circular dependencies; each crate is a independently testable unit.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Data Lifecycle: From Disk to AI Context
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File System (on disk)
        │
        │ [1] Async scan (tokio async fs + rayon par_iter)
        ▼
FileEntry { path, size, mtime }
        │
        │ [2] Include/Exclude filtering
        ▼
FilteredFileEntry
        │
        │ [3] Git info enrichment (optional, git CLI)
        ▼
GitEnrichedFile { change_count, last_commit }
        │
        │ [4] Content read
        ▼
RawFileContent
        │
        │ [5] Processing pipeline (optional)
        │     ├── tree-sitter compression
        │     ├── Comment removal
        │     └── Empty-line removal
        ▼
ProcessedFile { content, tokens, chars }
        │
        │ [6] Secretlint scan (optional)
        ▼
SecureProcessedFile { is_suspicious, suspicious_patterns? }
        │
        │ [7] Format serialization
        ▼
PackOutput { xml | markdown | json | plain }
        │
        │ [8] Written to disk
        ▼
repomix-output.{xml|md|json|txt}
        │
        │ [9] Consumed by AI Consumer
        ▼
LLM Context Window
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Design Highlights
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;[2] → [3] Ordered Dependency&lt;/strong&gt;: Filter by include/exclude rules first, then enrich with Git info. Git operations are heavy (spawns subprocesses), so executing them only on the known file set is more efficient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[5] tree-sitter pipeline&lt;/strong&gt;: Tree-sitter provides incremental parsing. For large files, only the changed parts are re-parsed, not the full file — a detail of performance optimization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[7] Lazy format binding&lt;/strong&gt;: The choice of output format is deferred to the last stage of the processing pipeline. This means all formats share the same intermediate representation &lt;code&gt;ProcessedFile&lt;/code&gt;, making it easy to extend with new formats.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Core Design Decisions and Trade-offs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Decision 1: Rust
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Benefit&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Speed: 10–20×&lt;/td&gt;
&lt;td&gt;Steep learning curve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory safety&lt;/td&gt;
&lt;td&gt;Longer compile times&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Single binary deployment&lt;/td&gt;
&lt;td&gt;Debug complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP ecosystem alignment&lt;/td&gt;
&lt;td&gt;Ecosystem younger than JS's&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Why Rust instead of Go?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stronger type system (Traits + generics), richer abstraction capabilities&lt;/li&gt;
&lt;li&gt;Better WASM support (potential for future browser-side execution)&lt;/li&gt;
&lt;li&gt;Async Rust (tokio) approaches Go's performance in I/O-bound scenarios&lt;/li&gt;
&lt;li&gt;Natural affinity with the AI/ML ecosystem (&lt;code&gt;tiktoken-rs&lt;/code&gt;, &lt;code&gt;burn&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Decision 2: Tokio over async-std
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Tokio&lt;/strong&gt; was chosen because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Rust community's preferred async runtime&lt;/li&gt;
&lt;li&gt;A more mature ecosystem&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tokio::Mutex&lt;/code&gt; is more controllable in MCP concurrency isolation scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Decision 3: Plaintext JSON Over Protocol Buffers for Configuration
&lt;/h3&gt;

&lt;p&gt;Uses JSON because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easier for humans to edit and diff&lt;/li&gt;
&lt;li&gt;Maintains format consistency with the original Repomix's &lt;code&gt;repomix.config.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;JSON Schema can be migrated to the TypeScript ecosystem (Webpack, ESLint toolchains, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Decision 4: Git CLI Subprocess over libgit2
&lt;/h3&gt;

&lt;p&gt;Calls the system &lt;code&gt;git&lt;/code&gt; command instead of using &lt;code&gt;git2&lt;/code&gt; (libgit2 bindings):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git CLI has richer behavior and covers more corner cases&lt;/li&gt;
&lt;li&gt;Avoids libgit2 version compatibility issues&lt;/li&gt;
&lt;li&gt;In the MCP scenario, each pack operation is an independent subprocess, naturally isolated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Trade-off&lt;/strong&gt;: Depends on &lt;code&gt;git&lt;/code&gt; being in PATH. Without git, functionality degrades gracefully rather than failing — this is an intentional fail-soft design.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decision 5: Four Output Formats Instead of One
&lt;/h3&gt;

&lt;p&gt;Argues against a "one format serves all" approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLMs have different token efficiency across formats&lt;/li&gt;
&lt;li&gt;XML is strongly structured but verbose&lt;/li&gt;
&lt;li&gt;Markdown is readable but has high parsing cost&lt;/li&gt;
&lt;li&gt;Plain is the most token-efficient but lacks metadata&lt;/li&gt;
&lt;li&gt;JSON is suitable for programmatic consumption&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. The Philosophy of Configuration: Layered Overrides and the Principle of Least Surprise
&lt;/h2&gt;

&lt;p&gt;repomix-rs's configuration system follows the &lt;strong&gt;Layer Cake Pattern&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;┌─────────────────────────────────────────────────────┐
│  CLI Flags   (highest priority, appends, not replace)│
├─────────────────────────────────────────────────────┤
│  ./repomix.config.json   (project-level)             │
├─────────────────────────────────────────────────────┤
│  ~/.repomix/repomix.config.json                     │
│  (global user-level)                                │
├─────────────────────────────────────────────────────┤
│  Hardcoded Defaults   (in-code defaults)             │
└─────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The three layers merge using the &lt;strong&gt;append-override&lt;/strong&gt; principle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--include&lt;/code&gt; appends to existing rules, does not replace&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--ignore&lt;/code&gt; appends to existing rules, does not replace&lt;/li&gt;
&lt;li&gt;Inner configuration overrides outer fields of the same name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rationale is &lt;strong&gt;"local config takes priority; global config provides the baseline"&lt;/strong&gt;, preventing global configuration from inadvertently polluting individual projects — consistent with the Unix philosophy of &lt;em&gt;"explicit over implicit"&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alignment with &lt;code&gt;.gitignore&lt;/code&gt; Design
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;.repomixignore&lt;/code&gt; syntax is fully aligned with &lt;code&gt;.gitignore&lt;/code&gt;. This is not accidental:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git-familiar developers have zero learning cost&lt;/li&gt;
&lt;li&gt;Glob semantics are already "consensus" in millions of engineers' minds&lt;/li&gt;
&lt;li&gt;Reusable tooling (e.g., ignore rules from &lt;code&gt;gitignore.io&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. MCP: Turning Tools into AI-Native Capabilities
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is Model Context Protocol (MCP)?
&lt;/h3&gt;

&lt;p&gt;MCP is an open protocol championed by Anthropic, defining a standardized AI Agent ↔ Tool communication interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────┐        stdio JSON-RPC        ┌──────────────┐
│  Client      │ ◄────────────────────────────►│  Server      │
│ (Claude,     │                              │ (repomix-mcp)│
│  Cursor)     │                              │              │
└──────────────┘                              └──────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The protocol layer has only two core primitives: &lt;code&gt;tools/list&lt;/code&gt; and &lt;code&gt;tools/call&lt;/code&gt;, but through these two primitives, powerful tool compositions can be built.&lt;/p&gt;

&lt;h3&gt;
  
  
  repomix-rs's Role in MCP
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User question
    ▼
Claude Desktop (MCP Client)
    "I need to understand this project's auth module"
    ▼
tools/call(pack_codebase, {directory: ".", compress: true})
    ▼
repomix-mcp Server
pack_directory(".") ──► repomix-core
    Tree-sitter compression (retains only auth-related function signatures)
    ▼
Returns PackResult
    ▼
Claude Desktop injects result into context
    ▼
Claude understands project structure and answers the question
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why "Native" MCP Support Matters
&lt;/h3&gt;

&lt;p&gt;The original Repomix has no MCP, meaning it is just a &lt;strong&gt;CLI tool&lt;/strong&gt;. For an AI Agent to use it, it must:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Spawn a subprocess to call the CLI&lt;/li&gt;
&lt;li&gt;Parse text output&lt;/li&gt;
&lt;li&gt;Manage the token budget itself&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;repomix-rs's MCP Server &lt;strong&gt;turns the pack operation into an AI-native capability&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent issues a JSON-RPC call and receives a structured result&lt;/li&gt;
&lt;li&gt;Result is directly injected into the Agent's workflow&lt;/li&gt;
&lt;li&gt;No lifecycle management burden on the Agent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This design upgrades repomix-rs from "a tool" to "an infrastructure component".&lt;/p&gt;




&lt;h2&gt;
  
  
  8. The Source of Performance: A Rust Architect's Perspective
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bottleneck Breakdown
&lt;/h3&gt;

&lt;p&gt;A single pack operation roughly has four stages:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Compute Characteristics&lt;/th&gt;
&lt;th&gt;repomix-rs Implementation&lt;/th&gt;
&lt;th&gt;Original Repomix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;File discovery&lt;/td&gt;
&lt;td&gt;I/O + lightweight matching&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rayon::par_iter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Single-threaded &lt;code&gt;fs.scandir&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content reading&lt;/td&gt;
&lt;td&gt;I/O-intensive&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tokio::fs::read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;async fs (libuv single-threaded)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AST compression&lt;/td&gt;
&lt;td&gt;CPU-intensive&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;rayon&lt;/code&gt; parallel tree-sitter&lt;/td&gt;
&lt;td&gt;Single-threaded JS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output writing&lt;/td&gt;
&lt;td&gt;I/O-intensive&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tokio::fs::write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fs.write&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Why 10–20× Speedup?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Theoretical level:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;repomix-rs employs a &lt;strong&gt;dual-engine architecture of Rayon data parallelism + Tokio async I/O&lt;/strong&gt; — a design capability unique to Rust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Pseudo-code illustration&lt;/span&gt;
&lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="nf"&gt;.par_iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.for_each&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&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;rt&lt;/span&gt;&lt;span class="nf"&gt;.block_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="py"&gt;.path&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;compressed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tree_sitter_compress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;result_tx&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;ProcessedFile&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compressed&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&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;The key point: &lt;code&gt;par_iter()&lt;/code&gt; causes Rayon to automatically utilize all available cores, while &lt;code&gt;tokio::fs::read&lt;/code&gt; releases the thread back to the thread pool while waiting for I/O. The original Node.js "concurrency" is &lt;strong&gt;cooperative concurrency&lt;/strong&gt; based on the event loop, which cannot parallelize CPU-intensive tasks across cores — this is why the tree-sitter compression stage shows the largest gap (20×+).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engineering level:&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;Optimization Technique&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;Memory-mapped I/O (mmap)&lt;/td&gt;
&lt;td&gt;Reduces copying, especially for large files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zero-copy string slicing&lt;/td&gt;
&lt;td&gt;Tree-sitter output avoids memory allocation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Streaming output&lt;/td&gt;
&lt;td&gt;No full buffering needed, T=O(1) memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Arc&lt;/code&gt; shared config&lt;/td&gt;
&lt;td&gt;Zero-copy read access to config in multi-threaded scenarios&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Early filtering&lt;/td&gt;
&lt;td&gt;Applies ignore rules before reading file contents&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  9. Security Architecture: A Multi-Layer Defense System
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌───────────────────────────────────────────────────────────────────────┐
│ Layer 1: Configuration Layer                                         │
│  • .repomixignore excludes known dangerous paths                    │
│  • Default excludes (node_modules, .git, etc.)                      │
├───────────────────────────────────────────────────────────────────────┤
│ Layer 2: Scanning Layer (Secretlint)                                 │
│  • Regex matching for API Keys, Tokens, private keys                │
│  • Scan results configurable: warn / exclude / ignore               │
├───────────────────────────────────────────────────────────────────────┤
│ Layer 3: Output Layer                                                │
│  • Suspicious files flagged, with pattern description attached       │
│  • Supports --exclude-suspicious for hard filtering                 │
├───────────────────────────────────────────────────────────────────────┤
│ Layer 4: Runtime Layer (Rust memory safety)                          │
│  • No buffer overflows / Use-After-Free                              │
│  • No memory leaks (RAII)                                            │
│  • No data races (Send + Sync trait constraints)                     │
└───────────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Defense in Depth&lt;/strong&gt; is the core principle of security design. repomix-rs does not rely on a single security mechanism; it provides protection at every layer. Rust's inclusion transforms Layer 4 from "as safe as possible" into "compile-time guaranteed safety". For a tool that processes user code, potentially encountering sensitive content, this is a qualitative leap.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Relationship with Mainstream AI Toolchains
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Position in the AI Coding Toolchain
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer workflow
  ├─ Code editing → IDE (VSCode / Cursor)
  ├─ Code review → LLM + repomix-rs output
  ├─ Code generation → Cursor / Copilot
  ├─ Code knowledge retrieval → RAG / Embedding
  └── Codebase context injection ─────────────────────────────┐
                                                                │
  AI Agent capability stack                                    │
  ├─ Tool invocation (Function Calling) ──────────────────────┤
  ├─ Context management (Context Management) ─────────────────┤
  │   └── repomix-rs provides structured code context         │
  ├─ Long-term memory (Memory / RAG)                          │
  └─ Autonomous execution (Agentic Workflow)                  │
                                                                │
  MCP Ecosystem                                                │
  ├─ MCP Servers: filesystem, sqlite, …                       │
  ├─ MCP Servers: repomix-rs (code context) ──────────────────┤
  └─ MCP Servers: your custom tools                           │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;repomix-rs occupies the &lt;strong&gt;codebase context provider&lt;/strong&gt; niche in the AI coding toolchain. Its irreplaceability stems from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It can "see" the entire project structure (RAG cannot)&lt;/li&gt;
&lt;li&gt;It understands code's token cost (manual organization cannot)&lt;/li&gt;
&lt;li&gt;It can be natively consumed by AI (only achievable with MCP architecture)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Relationship with RAG: Complementary, Not Competitive
&lt;/h3&gt;

&lt;p&gt;RAG (Retrieval-Augmented Generation) addresses the problem of &lt;em&gt;"knowing where to look"&lt;/em&gt;, while repomix-rs addresses the problem of &lt;em&gt;"how to transmit completely"&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;Dimension&lt;/th&gt;
&lt;th&gt;RAG&lt;/th&gt;
&lt;th&gt;repomix-rs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Applicable scenario&lt;/td&gt;
&lt;td&gt;Large knowledge base retrieval&lt;/td&gt;
&lt;td&gt;Small-to-medium project full context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accuracy&lt;/td&gt;
&lt;td&gt;Depends on embedding quality&lt;/td&gt;
&lt;td&gt;Precise and complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Token cost&lt;/td&gt;
&lt;td&gt;Charged by retrieved chunks&lt;/td&gt;
&lt;td&gt;Controllable compression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Setup complexity&lt;/td&gt;
&lt;td&gt;High (requires vector DB)&lt;/td&gt;
&lt;td&gt;Low (single command)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time&lt;/td&gt;
&lt;td&gt;Requires index updates&lt;/td&gt;
&lt;td&gt;Real-time pack&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Best practice&lt;/strong&gt;: Use RAG + repomix-rs together — RAG for large knowledge bases; repomix-rs for current project context.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Project Roadmap and Ecosystem Position
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Current (v2.0) Capability Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Core packing&lt;/td&gt;
&lt;td&gt;✅ Production-ready&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language support&lt;/td&gt;
&lt;td&gt;⚠️ 10 (extensible)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP Server&lt;/td&gt;
&lt;td&gt;✅ Production-ready&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remote repository packing&lt;/td&gt;
&lt;td&gt;✅ Production-ready&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secretlint integration&lt;/td&gt;
&lt;td&gt;✅ Basic, configurable scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Token calculation&lt;/td&gt;
&lt;td&gt;✅ Precise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;✅ 10–40× over original&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Documentation&lt;/td&gt;
&lt;td&gt;⚠️ Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Community contributions&lt;/td&gt;
&lt;td&gt;🔄 Growing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Future Directions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Near-term (v2.x):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More language support (tree-sitter language extensions)&lt;/li&gt;
&lt;li&gt;Incremental packing (re-process only changed files based on last pack result)&lt;/li&gt;
&lt;li&gt;Pluggable output formats (define your own markdown templates)&lt;/li&gt;
&lt;li&gt;Richer MCP tools (diff against baseline, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Medium-term (v3.x):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;repomix-lsp&lt;/code&gt;: Language Server Protocol integration for real-time code context maintenance in IDEs&lt;/li&gt;
&lt;li&gt;Streaming MCP: chunked transfer for large repositories&lt;/li&gt;
&lt;li&gt;Multi-repository aggregation: selective packing of monorepo sub-packages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Long-term:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repomix-rs becomes one of AI Agents' standard tools (equivalent to curl's position in the HTTP toolchain)&lt;/li&gt;
&lt;li&gt;Deep IDE integration (VSCode extension, JetBrains plugin)&lt;/li&gt;
&lt;li&gt;WASM sandbox: browser-side execution, no local installation required&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ecosystem Position: Why Rust?
&lt;/h3&gt;

&lt;p&gt;Boldly choosing Rust to rewrite developer tools is itself a technical signal. Bun chose Rust; parts of Vite chose Rust (Rolldown was rewritten in Rust). repomix-rs stands within this trend, proving that &lt;strong&gt;tools that are performance-sensitive, security-sensitive, and tightly coupled with the AI ecosystem are entering Rust's golden age&lt;/strong&gt;.&lt;/p&gt;




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

&lt;p&gt;repomix-rs is not a simple "Rust port" of the original Repomix. It is a &lt;strong&gt;tool re-architected around AI code consumption scenarios&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Layered architecture&lt;/strong&gt;: Crates are cleanly split with clear responsibilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data pipeline&lt;/strong&gt;: Token counting, compression, and filtering compose a combinable pipeline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP-native&lt;/strong&gt;: First-class AI Agent integration capability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: Rayon + Tokio dual-engine, fully leveraging modern hardware&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Multi-layer defense + Rust memory safety baseline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choosing repomix-rs means choosing &lt;strong&gt;architecture for the future&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/sopaco/repomix-rs" rel="noopener noreferrer"&gt;https://github.com/sopaco/repomix-rs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt;: &lt;code&gt;npm install -g repomix-rs&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>rust</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>MemClaw: Give OpenClaw a 'Super Brain', Token Cost Slashed by 91%</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Mon, 06 Apr 2026 15:01:40 +0000</pubDate>
      <link>https://dev.to/sopaco/cortex-memorygei-openclaw-zhuang-shang-chao-ji-da-nao-token-cheng-ben-bao-jiang-91-2g72</link>
      <guid>https://dev.to/sopaco/cortex-memorygei-openclaw-zhuang-shang-chao-ji-da-nao-token-cheng-ben-bao-jiang-91-2g72</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zhledziq1kyh2f9c7ub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zhledziq1kyh2f9c7ub.png" alt=" " width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you've used OpenClaw before, you know the feeling all too well: once a conversation ends, all the API keys, technical decisions, and project background from previous chats seem to be wiped away by an eraser. This isn't a bug in OpenClaw—it's a common dilemma faced by all LLM Agents: limited context windows, and complete memory loss when the session ends.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The common solution in the community is memory plugins like OpenViking, but have you ever wondered: &lt;strong&gt;Is there a solution that can remember more while also saving a huge amount of Token costs?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer is a resounding yes. &lt;strong&gt;MemClaw&lt;/strong&gt;(Plugin For OpenClaw basded on the &lt;a href="https://github.com/sopaco/cortex-mem" rel="noopener noreferrer"&gt;Cortex Memory&lt;/a&gt;) has burst onto the scene, scoring the &lt;strong&gt;highest at 68.42%&lt;/strong&gt; in the official LoCoMo benchmark (surpassing OpenViking's 52.08%), while reducing Token consumption by &lt;strong&gt;11 times&lt;/strong&gt; compared to OpenClaw+LanceDB, and improving score efficiency per thousand Tokens by &lt;strong&gt;18 times&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This isn't magic—it's the power of architecture. Let's take a closer look.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Does OpenClaw Need "External Memory"?
&lt;/h2&gt;

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

&lt;p&gt;If you're a heavy user of OpenClaw, these scenarios must be familiar:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 1: Repeatedly asking for API keys&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;User: Call Alibaba Cloud OSS to upload a file
Agent: What is your AccessKey?
User: xxx
(Next day, new session)
User: Upload another file for me
Agent: What is your AccessKey?
User: (frustrated) Didn't I tell you yesterday...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Scenario 2: "Amnesia" after long conversations&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;User: My project goal is to build a B2B sales tool
(After 50 rounds of conversation, discussing various technical details)
User: Based on my goal mentioned earlier, help me design the core architecture
Agent: What was the goal you mentioned earlier?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Scenario 3: Repeating the same mistakes&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;User: Call sales-db-query skill, incorrect parameter format
Agent: (error)
User: Correct format is {...}
(New session)
User: Call this skill again
Agent: (same error again)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The root cause of these issues: &lt;strong&gt;OpenClaw's native memory system has "goldfish memory"&lt;/strong&gt;—once the context window is full, earlier content gets squeezed out; when the session ends, all states reset to zero.&lt;/p&gt;




&lt;h2&gt;
  
  
  OpenViking's Solution vs Cortex Memory's Overwhelming Advantage
&lt;/h2&gt;

&lt;p&gt;OpenViking indeed solves this problem by giving Agents long-term memory through "virtual file system + vector search". But &lt;strong&gt;MemClaw&lt;/strong&gt;(Plugin For OpenClaw basded on the &lt;a href="https://github.com/sopaco/cortex-mem" rel="noopener noreferrer"&gt;Cortex Memory&lt;/a&gt;) delivers a &lt;strong&gt;crushing blow&lt;/strong&gt; on top of this:&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmark data speaks for itself
&lt;/h3&gt;

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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;LoCoMo Benchmark Score&lt;/th&gt;
&lt;th&gt;Avg Tokens/Question&lt;/th&gt;
&lt;th&gt;Score per 1K Tokens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MemClaw&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;68.42%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~2,900&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;23.6&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenViking + OpenClaw&lt;/td&gt;
&lt;td&gt;52.08%&lt;/td&gt;
&lt;td&gt;~2,769&lt;/td&gt;
&lt;td&gt;18.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenClaw + LanceDB&lt;/td&gt;
&lt;td&gt;44.55%&lt;/td&gt;
&lt;td&gt;~33,490&lt;/td&gt;
&lt;td&gt;1.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenClaw Native Memory&lt;/td&gt;
&lt;td&gt;35.65%&lt;/td&gt;
&lt;td&gt;~15,982&lt;/td&gt;
&lt;td&gt;2.2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key insight&lt;/strong&gt;: &lt;strong&gt;MemClaw&lt;/strong&gt;(Plugin For OpenClaw basded on the &lt;a href="https://github.com/sopaco/cortex-mem" rel="noopener noreferrer"&gt;Cortex Memory&lt;/a&gt;) not only achieves the highest score but also dominates in Token efficiency—compared to OpenClaw+LanceDB, &lt;strong&gt;Token savings reach 91%, with efficiency improved by 18 times&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Can Cortex Memory Achieve This?
&lt;/h3&gt;

&lt;p&gt;The secret lies in its &lt;strong&gt;three-layer memory architecture&lt;/strong&gt;:&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;The problem with traditional approaches&lt;/strong&gt;: either load everything (Token explosion) or only store summaries (loss of details).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cortex Memory's solution&lt;/strong&gt;: Progressive layered retrieval—first quickly filter with 100-Token summaries, then refine with 2,000-Token overviews, and finally load only the truly needed full content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Retrieving 100 memories, traditional approaches need to load 100 × full content; Cortex Memory only needs 100 × 100 Tokens (L0 layer) plus a small number of L1/L2 layers.&lt;/p&gt;




&lt;h2&gt;
  
  
  MemClaw: One-Click Upgrade for OpenClaw
&lt;/h2&gt;

&lt;p&gt;Cortex Memory provides an out-of-the-box OpenClaw plugin—&lt;strong&gt;MemClaw&lt;/strong&gt;.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Installation with just one command
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openclaw plugins &lt;span class="nb"&gt;install&lt;/span&gt; @memclaw/memclaw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Extremely simple configuration
&lt;/h3&gt;

&lt;p&gt;Add to &lt;code&gt;openclaw.json&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;"plugins"&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;"entries"&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;"memclaw"&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;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"config"&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;"llmApiKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-api-key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"embeddingApiKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-api-key"&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;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"agents"&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;"defaults"&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;"memorySearch"&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;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Disable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;native&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;memory&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;
  
  
  Core tools at a glance
&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;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cortex_search&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Layered semantic search, controllable return layer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cortex_recall&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Retrieve memories with full context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cortex_add_memory&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Store important information for future retrieval&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cortex_commit_session&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Commit session and trigger memory extraction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cortex_migrate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One-click migration of OpenClaw native memories&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cortex_maintenance&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Regular maintenance (cleanup, rebuild index)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Real-World Results: From "Forgetful" to "Elephant Memory"
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Case 1: Skill invocation experience accumulation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Calling a certain skill always results in parameter errors; need to retry from scratch in every new session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MemClaw solution&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;User: Call sales-db-query skill, query national sales data
Agent: (call succeeds, MemClaw automatically records correct parameter format)
(Three days later, new session)
User: Query East China region data again
Agent: (MemClaw retrieves previous successful case, uses correct format directly)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Case 2: Long conversation goals don't get lost
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: After 50 rounds of conversation, the Agent forgets the originally set project goal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MemClaw solution&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;User: My project goal is to build a B2B sales tool, focusing on stability
(After 100 rounds of conversation)
User: Based on my earlier goal, design the core architecture
Agent: (MemClaw retrieves original goal, outputs solution that meets constraints)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Case 3: Cross-session memory reuse
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Need to re-enter API keys in every new session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MemClaw solution&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 A: User enters OSS key, MemClaw stores to cortex://user/preferences/
Session B: User requests file upload, MemClaw automatically retrieves key, no need to repeat input
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Technical Highlights: Why Choose Cortex Memory?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Rust Implementation, Maximum Performance
&lt;/h3&gt;

&lt;p&gt;Compared to Node.js-based memory solutions, Cortex Memory is written in Rust:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory safety&lt;/strong&gt;: No GC pauses, no memory leaks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrent processing&lt;/strong&gt;: Tokio async runtime, excellent performance under high concurrency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low resource usage&lt;/strong&gt;: 60%+ less memory under same load&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Fully Localized, Data Privacy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;All memories stored locally in &lt;code&gt;cortex-data/&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;Vector database uses local Qdrant (or remote)&lt;/li&gt;
&lt;li&gt;Zero cloud dependencies, suitable for sensitive data scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Multi-Tenant Isolation
&lt;/h3&gt;

&lt;p&gt;Supports multiple isolated memory spaces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cortex-data/
├── tenants/
│   ├── project-a/     # Memories for Project A
│   ├── project-b/     # Memories for Project B
│   └── personal/      # Personal memories
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Rich Interface
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CLI tool&lt;/strong&gt;: &lt;code&gt;cortex-mem&lt;/code&gt; command-line management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REST API&lt;/strong&gt;: &lt;code&gt;/api/v2/*&lt;/code&gt; endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Protocol&lt;/strong&gt;: Supports Claude Desktop, Cursor, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Dashboard&lt;/strong&gt;: Svelte 5 visual management&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Install dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Qdrant vector database&lt;/span&gt;
docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 6333:6333 &lt;span class="nt"&gt;-p&lt;/span&gt; 6334:6334 qdrant/qdrant

&lt;span class="c"&gt;# Install MemClaw plugin&lt;/span&gt;
openclaw plugins &lt;span class="nb"&gt;install&lt;/span&gt; @memclaw/memclaw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Configure API keys
&lt;/h3&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;"plugins"&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;"entries"&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;"memclaw"&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;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"config"&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;"llmApiBaseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.openai.com/v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"llmApiKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sk-xxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"llmModel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpt-5-mini"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"embeddingApiBaseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.openai.com/v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"embeddingApiKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sk-xxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"embeddingModel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text-embedding-3-small"&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;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;
  
  
  3. Start using
&lt;/h3&gt;

&lt;p&gt;Restart OpenClaw Gateway, MemClaw will automatically start background services. Now your Agent possesses a "super brain".&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Cortex Memory is not just a simple memory storage—it's &lt;strong&gt;AI Agent's cognitive infrastructure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It solves the paradox of "memory precision vs Token cost" with its three-layer architecture, guarantees performance and stability with Rust implementation, and achieves seamless integration with OpenClaw through the MemClaw plugin.&lt;/p&gt;

&lt;p&gt;If you're tired of Agents' "goldfish memory", if you're心疼 Token consumption, if you need a production-grade long-term memory solution—&lt;strong&gt;Cortex Memory is worth trying&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Project URL&lt;/strong&gt;: &lt;a href="https://github.com/sopaco/cortex-mem" rel="noopener noreferrer"&gt;https://github.com/sopaco/cortex-mem&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MemClaw Plugin&lt;/strong&gt;: &lt;a href="https://github.com/sopaco/cortex-mem/tree/main/examples/%40memclaw/plugin" rel="noopener noreferrer"&gt;examples/@memclaw/plugin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full Documentation&lt;/strong&gt;: &lt;a href="https://github.com/sopaco/cortex-mem/tree/main/litho.docs/zh" rel="noopener noreferrer"&gt;litho.docs/zh&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>openclaw</category>
    </item>
    <item>
      <title>How Cowork &amp; Coding Agent Only Modifies Files That Need Changing</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Sun, 25 Jan 2026 10:14:32 +0000</pubDate>
      <link>https://dev.to/sopaco/how-cowork-coding-agent-only-modifies-files-that-need-changing-2h99</link>
      <guid>https://dev.to/sopaco/how-cowork-coding-agent-only-modifies-files-that-need-changing-2h99</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cowork Forge - An open-source AI multi-agent development platform, serving as both an embeddable AI Coding engine and a standalone production-grade development tool. GitHub: &lt;a href="https://github.com/sopaco/cowork-forge" rel="noopener noreferrer"&gt;https://github.com/sopaco/cowork-forge&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you ever encountered this scenario:&lt;/p&gt;

&lt;p&gt;Your project has been under development for some time, and suddenly the product manager runs over and says: "We need to add a 'tags' feature for users."&lt;/p&gt;

&lt;p&gt;If you follow the traditional development process, you might need to: manually analyze which files need modification, modify the data model, update API interfaces, modify frontend pages, update test cases... and worry about whether you've missed any files.&lt;/p&gt;

&lt;p&gt;If you use AI tools, many tools choose "full regeneration"—regenerating the entire project's code. But this brings new problems: your previously manually optimized code gets overwritten, your added comments and documentation are lost, unrelated files get modified, and you need to review all the code again.&lt;/p&gt;

&lt;p&gt;This is the problem that "incremental code updates" aims to solve.&lt;/p&gt;

&lt;p&gt;The core idea of &lt;strong&gt;incremental code updates&lt;/strong&gt; is: intelligently identify the scope of requirement changes, only modify affected files, and preserve user custom code.&lt;/p&gt;

&lt;p&gt;In this article, I'll explore Cowork Forge's incremental code update mechanism in depth, looking at how it analyzes change impact, generates precise update plans, and how to apply it in actual projects.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem with "Full Regeneration"
&lt;/h2&gt;

&lt;p&gt;Before discussing incremental updates, let's look at the problems brought by "full regeneration."&lt;/p&gt;

&lt;h3&gt;
  
  
  Typical Full Regeneration Workflow
&lt;/h3&gt;

&lt;p&gt;When using some AI tools for code generation, the typical process is: requirement change → AI analyzes new requirements → regenerate all files → overwrite original files → user custom code lost → need to review all code again → manually restore custom code.&lt;/p&gt;

&lt;p&gt;The problem with this workflow is: AI doesn't know which code was manually added by users and which was AI-generated, so it overwrites all files, including user custom code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problems with Full Regeneration
&lt;/h3&gt;

&lt;p&gt;First, &lt;strong&gt;overwriting user custom code&lt;/strong&gt;. This is the most serious problem. Suppose you added performance optimization code in a certain file—if AI fully regenerates, your optimization code gets overwritten. Your detailed field descriptions and constraint conditions added to the user data model are also lost. Your custom validation logic added to user business logic is also overwritten.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;losing comments and documentation&lt;/strong&gt;. Your added detailed comments and documentation are also lost. These comments and documentation might contain important business logic explanations, design decision records, API usage examples, etc. Losing this information increases subsequent maintenance difficulty.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;modifying unrelated files&lt;/strong&gt;. Full regeneration might modify some unrelated files, increasing unnecessary risk. For example, AI might modify a completely unchanged configuration file, causing configuration to be reset.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;need to review all code again&lt;/strong&gt;. Even if only 10% of files truly need modification, you need to review 100% of the code, wasting a lot of time. Git diff shows a large number of changes, even though most changes are unnecessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Actual Case: Full Regeneration of a Feature Module
&lt;/h3&gt;

&lt;p&gt;Suppose you have a user management module containing user data model, user API handlers, user route definitions, user business logic, and other files. Now you need to add a "user tags" feature.&lt;/p&gt;

&lt;p&gt;If you use full regeneration, AI will regenerate all files, adding tag fields, tag-related APIs, tag routes, tag business logic. But the problem is, your previously added caching logic in user business logic gets overwritten, your added logging in user API handlers gets overwritten, your added field validation in user data model gets overwritten.&lt;/p&gt;

&lt;p&gt;What's the consequence? You need to manually restore all custom code, need to retest all features, and might introduce new bugs.&lt;/p&gt;

&lt;p&gt;If you use incremental updates, AI will analyze change impact, identify affected files, generate an incremental plan, only add tag fields, only add tag-related APIs, only add tag routes, only add tag business logic, preserve caching logic. What's the result? Custom code is preserved, only need to review changed parts, Git diff is clear and concise.&lt;/p&gt;

&lt;p&gt;This case clearly demonstrates the advantage of incremental updates: it only modifies files that truly need modification, preserves user custom code, and greatly reduces review and repair workload.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Ideas of Change Impact Analysis
&lt;/h2&gt;

&lt;p&gt;The core of incremental code updates is &lt;strong&gt;change impact analysis&lt;/strong&gt;—identifying which files and code are affected by requirement changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layers of Impact Analysis
&lt;/h3&gt;

&lt;p&gt;Change impact analysis can be divided into several layers: requirements layer analysis (identify changed requirements), design layer analysis (identify changed components), implementation layer analysis (identify changed modules), file layer analysis (identify affected files), code layer analysis (identify affected code snippets).&lt;/p&gt;

&lt;p&gt;The benefit of this layered analysis is: from macro to micro, gradually narrowing the impact scope, ensuring analysis accuracy.&lt;/p&gt;

&lt;p&gt;Requirements layer analysis identifies new requirements, deleted requirements, modified requirements. For example, if the PRD adds a "user tags" feature, this is a new requirement.&lt;/p&gt;

&lt;p&gt;Design layer analysis identifies components that need to be added, components that need to be modified. For example, the user data model needs to add a tags field, the user API handler needs to add tag-related interfaces.&lt;/p&gt;

&lt;p&gt;Implementation layer analysis identifies modules that need to be added, modules that need to be modified. For example, need to add a tag management module, need to modify the user management module.&lt;/p&gt;

&lt;p&gt;File layer analysis identifies files that need to be added, files that need to be modified. For example, need to add tag-related API files, need to modify user data model files.&lt;/p&gt;

&lt;p&gt;Code layer analysis identifies code snippets that need modification. For example, need to add a tags field in the User struct, need to add tag-related processing logic in user API handlers.&lt;/p&gt;

&lt;h3&gt;
  
  
  File Dependency Relationship Construction and Analysis
&lt;/h3&gt;

&lt;p&gt;The core of change impact analysis is constructing a file dependency relationship graph.&lt;/p&gt;

&lt;p&gt;The dependency relationship graph contains nodes (representing a file) and edges (representing dependency relationships). Nodes contain file path, file type, exported content, imported content. Edges contain dependency source, dependency target, dependency type (direct import, type reference, function call, data flow).&lt;/p&gt;

&lt;p&gt;The process of constructing a dependency relationship graph is: scan all source files, analyze each file, parse AST (Abstract Syntax Tree), extract imports and exports, add nodes, build dependency relationships.&lt;/p&gt;

&lt;p&gt;Impact propagation analysis finds direct dependencies (files that depend on the current file) and indirect dependencies (files that depend on direct dependencies), uses breadth-first search to traverse the dependency relationship graph, calculates propagation depth.&lt;/p&gt;

&lt;p&gt;The benefit of this dependency relationship analysis is: when a file is modified, it can quickly find all affected files, ensuring no files needing updates are missed.&lt;/p&gt;

&lt;h3&gt;
  
  
  API-Level Impact Propagation
&lt;/h3&gt;

&lt;p&gt;Besides file-level dependencies, we also need to analyze API-level impact.&lt;/p&gt;

&lt;p&gt;API-level impact analysis identifies API changes (add, delete, modify, rename), analyzes breaking changes, identifies all affected consumers. For example, if you modify an API signature, all code calling this API needs to be updated. AI will identify this affected code and include these changes in the incremental plan.&lt;/p&gt;

&lt;p&gt;The benefit of this API-level impact analysis is: it can ensure API changes don't break existing callers, guaranteeing system stability.&lt;/p&gt;




&lt;h2&gt;
  
  
  Incremental Update Mechanism Details
&lt;/h2&gt;

&lt;p&gt;After understanding change impact analysis, let's look at how Cowork Forge's incremental update mechanism works.&lt;/p&gt;

&lt;h3&gt;
  
  
  CodeUpdater's Working Principle
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;CodeUpdater&lt;/code&gt; is the core component responsible for incremental updates.&lt;/p&gt;

&lt;p&gt;It contains a dependency relationship graph, code analyzer, and impact analyzer. When receiving design changes, it analyzes change impact, generates an update plan, and optimizes the update plan.&lt;/p&gt;

&lt;p&gt;The dependency relationship graph is used to track dependencies between files, the code analyzer is used to analyze code structure, and the impact analyzer is used to analyze the scope of change impact.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update Plan Generation
&lt;/h3&gt;

&lt;p&gt;The process of generating an update plan is: sort files by dependency, generate update instructions for each file, add new files.&lt;/p&gt;

&lt;p&gt;Sorting files by dependency ensures correct dependency relationships—if file A depends on file B, then file B should be modified first. This can be achieved through topological sorting.&lt;/p&gt;

&lt;p&gt;Generating update instructions for each file analyzes file changes—if a file has changes, it's added to the update plan. Update instructions include file path, change type (add, modify, delete), change content.&lt;/p&gt;

&lt;p&gt;Adding new files generates templates for each new file. Templates are generated according to the project's coding standards and conventions, ensuring new files are consistent with existing code style.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Preserve User Custom Code
&lt;/h3&gt;

&lt;p&gt;Preserving user custom code is the core challenge of incremental updates. Cowork Forge uses the following strategies.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;code region marking&lt;/strong&gt;. AI-generated code adds markers, and user custom code also adds markers. This way, during incremental updates, AI can identify which code is AI-generated and which is user custom.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;code difference analysis&lt;/strong&gt;. It analyzes differences between original code and new code, identifies user custom code, and generates differences. This can be achieved by comparing ASTs of two versions.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;code merge strategy&lt;/strong&gt;. It analyzes original code, new code, and user code, identifies conflicts, resolves conflicts, and generates merged code. Merge strategies include: preserve user code, merge AI code, resolve conflicts.&lt;/p&gt;

&lt;p&gt;The benefit of this design is: user custom code is preserved, AI's new code is merged, conflicts are intelligently resolved, greatly reducing user workload.&lt;/p&gt;




&lt;h2&gt;
  
  
  Complete Process Demonstration
&lt;/h2&gt;

&lt;p&gt;Let's look at how incremental updates work through a complete case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario: Adding Tag Functionality to User Module
&lt;/h3&gt;

&lt;p&gt;Suppose we have a user management module, and now need to add tag functionality.&lt;/p&gt;

&lt;p&gt;The original user data model defines user ID, name, email, creation time, update time, and other fields, plus a user custom validation method that checks if user name is empty and if email contains @ symbol.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirement Change
&lt;/h3&gt;

&lt;p&gt;The requirement has changed, and the PRD adds a new requirement: users can add tags to tasks for categorization and filtering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design Change
&lt;/h3&gt;

&lt;p&gt;The design document is also updated, and the user table adds a tags field.&lt;/p&gt;

&lt;h3&gt;
  
  
  Incremental Update Process
&lt;/h3&gt;

&lt;p&gt;The incremental update process is: detect PRD change → compare old and new versions → identify requirement differences → map affected files → generate incremental plan → HITL confirm change plan → user confirms → code executor implements changes → verification module executes tests → verification results → if passed update TodoList status, if failed error analyzer diagnoses → analyze failure cause → if planning error return to mapping affected files, if execution error local fix, if environment error environment fix.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graph LR
    A[Detect PRD Change] --&amp;gt; B[Compare Old and New Versions]
    B --&amp;gt; C[Identify Requirement Differences]
    C --&amp;gt; D[Map Affected Files]
    D --&amp;gt; E[Generate Incremental Plan]
    E --&amp;gt; F[HITL Confirm Change Plan]
    F --&amp;gt; G{User Confirms?}
    G --&amp;gt;|Yes| H[Code Executor Implements Changes]
    G --&amp;gt;|No| I[Plan Adjustment]
    I --&amp;gt; D
    H --&amp;gt; J[Verification Module Executes Tests]
    J --&amp;gt; K{Verification Results?}
    K --&amp;gt;|Passed| L[Update TodoList Status]
    K --&amp;gt;|Failed| M[Error Analyzer Diagnoses]
    M --&amp;gt; N[Analyze Failure Cause]
    N --&amp;gt; O{Error Type?}
    O --&amp;gt;|Planning Error| D
    O --&amp;gt;|Execution Error| P[Local Fix]
    P --&amp;gt; J
    O --&amp;gt;|Environment Error| Q[Environment Fix]
    Q --&amp;gt; J

    classDef process fill:#e1f5fe,stroke:#01579b,stroke-width:2px
    classDef decision fill:#fff3e0,stroke:#e65100,stroke-width:2px
    classDef action fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px

    class A,B,C,D,E,F,H,J,L,M,N process
    class G,K,O decision
    class I,P,Q action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This flowchart shows the complete incremental update process. You can see this is an intelligent process with feedback loops—if problems occur, it intelligently analyzes the cause and takes appropriate measures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Change Impact Analysis
&lt;/h3&gt;

&lt;p&gt;AI will analyze design changes and identify affected files.&lt;/p&gt;

&lt;p&gt;Affected files include: user data model (add tags field, preserve user custom validate method), user API handler (update API processing logic, add include_tags parameter), user route definition (might need to update routes), user business logic (update business logic, add add_tag method), database migration (add new migration file).&lt;/p&gt;

&lt;h3&gt;
  
  
  Generate Incremental Plan
&lt;/h3&gt;

&lt;p&gt;AI will generate an incremental plan containing file updates and file creation.&lt;/p&gt;

&lt;p&gt;File updates include: user data model (add tags field, preserve user custom validate method), user API handler (update get_user handler, add include_tags parameter), user business logic (add add_tag method).&lt;/p&gt;

&lt;p&gt;File creation includes: database migration file (create new migration file).&lt;/p&gt;

&lt;h3&gt;
  
  
  HITL Confirm Change Plan
&lt;/h3&gt;

&lt;p&gt;User will review the change plan, seeing change plan summary (3 files modified, 1 file added, expected impact scope medium) and detailed changes (user data model adds tags field and preserves user custom validate method, user API handler updates get_user handler and adds include_tags parameter, user business logic adds add_tag method, create new database migration file).&lt;/p&gt;

&lt;h3&gt;
  
  
  Updated Code
&lt;/h3&gt;

&lt;p&gt;After update, the user data model adds a tags field (Option&amp;gt;), preserving the user custom validate method. Note: the user custom validate method is completely preserved!&lt;/p&gt;

&lt;h3&gt;
  
  
  Verification Results
&lt;/h3&gt;

&lt;p&gt;After code update completes, the verification module executes tests. The check report shows build status success, test status passed, all 18 test cases passed, user code preserved, migration applied.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical Challenges and Solutions
&lt;/h2&gt;

&lt;p&gt;Although incremental code updates are powerful, they also face some technical challenges.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complexity of Dependency Relationship Construction
&lt;/h3&gt;

&lt;p&gt;First, &lt;strong&gt;multi-language support&lt;/strong&gt;. Different programming languages have different dependency relationships, dynamic language dependency relationships are difficult to analyze statically, advanced features like macros and templates increase analysis difficulty.&lt;/p&gt;

&lt;p&gt;The solution is to support multi-language dependency analysis. Implement language analyzers for each language, use language-specific parsing tools. For dynamic languages, combine static analysis with runtime information.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;dynamic language support&lt;/strong&gt;. For dynamic languages, combine static analysis with runtime information. Use static analyzers to analyze code structure, use runtime analyzers to collect runtime information, merge results from both analyses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Boundary Case Identification and Handling
&lt;/h3&gt;

&lt;p&gt;First, &lt;strong&gt;circular dependency detection&lt;/strong&gt;. Detect circular dependencies, use depth-first search to traverse the dependency relationship graph, identify circular dependencies.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;conditional compilation handling&lt;/strong&gt;. Handle conditional compilation, identify conditional compilation directives, evaluate conditions, analyze dependencies within conditional blocks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance Optimization Strategies
&lt;/h3&gt;

&lt;p&gt;First, &lt;strong&gt;incremental analysis&lt;/strong&gt;. Only analyze changed parts, use caching, only analyze changed files. If a file is in cache, use cached results; otherwise, reanalyze and update cache.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;parallel analysis&lt;/strong&gt;. Analyze multiple files in parallel, use async tasks to process multiple files in parallel, improving analysis speed.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;cache optimization&lt;/strong&gt;. Use cache optimization performance, check cache, if cache hit, directly return cached results; otherwise, execute analysis and update cache.&lt;/p&gt;




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

&lt;p&gt;Incremental code updates are one of Cowork Forge's core features. Through intelligent change impact analysis, it only modifies affected files and preserves user custom code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Value of Incremental Updates
&lt;/h3&gt;

&lt;p&gt;First, &lt;strong&gt;preserve user custom code&lt;/strong&gt;. Won't overwrite user manually optimized code, preserve user-added comments and documentation, maintain code's personal style.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;improve development efficiency&lt;/strong&gt;. Only modify necessary files, reduce code review workload, lower risk of introducing bugs.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;version control friendly&lt;/strong&gt;. Git diff is clear and concise, change history is easy to track, code review is more efficient.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;support iterative development&lt;/strong&gt;. Rapidly respond to requirement changes, flexibly adjust feature implementation, maintain code quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Applicable Scenarios and Limitations
&lt;/h3&gt;

&lt;p&gt;Incremental updates are suitable for projects with frequent requirement changes, projects that need to preserve user custom code, incremental development of large projects, and multi-user collaboration projects.&lt;/p&gt;

&lt;p&gt;But incremental updates also have limitations: projects with complex dependency relationships might have inaccurate analysis, dynamic language dependency analysis is more difficult, needs good code structure support, first-time use has some learning cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Future Improvement Directions
&lt;/h3&gt;

&lt;p&gt;First, &lt;strong&gt;smarter dependency analysis&lt;/strong&gt;. Support more programming languages, improve dynamic language analysis accuracy, support more complex code patterns.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;more precise change identification&lt;/strong&gt;. Improve change impact identification precision, reduce false positives and false negatives, support more fine-grained changes.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;smarter code merging&lt;/strong&gt;. Improve code merging accuracy, support more complex conflict resolution, provide better merge suggestions.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;better performance optimization&lt;/strong&gt;. Further improve analysis speed, reduce memory usage, support ultra-large projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recommendations for Developers
&lt;/h3&gt;

&lt;p&gt;First, &lt;strong&gt;maintain good code structure&lt;/strong&gt;. Clear module division, clear dependency relationships, consistent coding style.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;use code markers&lt;/strong&gt;. Mark AI-generated code, mark user custom code, facilitating incremental update identification.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;regularly review change plans&lt;/strong&gt;. Carefully review AI-generated change plans, confirm change rationality, promptly adjust inappropriate changes.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;fully leverage version control&lt;/strong&gt;. Use Git to manage code changes, commit code regularly, facilitating rollback and backtracking.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Incremental code updates are an important feature of AI-driven software development. It solves the problems brought by full regeneration, making AI tools more practical and reliable.&lt;/p&gt;

&lt;p&gt;Through intelligent change impact analysis, incremental updates can precisely identify files that need modification, preserve user custom code, and improve development efficiency.&lt;/p&gt;

&lt;p&gt;As AI technology develops, incremental updates will become smarter and more precise, providing developers with better experience.&lt;/p&gt;

&lt;p&gt;Future software development isn't AI completely replacing humans, but AI and humans collaborating deeply. Incremental updates are an important embodiment of this collaboration.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Related Reading&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="//./01-From-Idea-to-Code-How-AI-Multi-Agents-Work-Like-a-Team-to-Write-Software.md"&gt;From Idea to Code: How an AI Multi-Agent System Works Like a Team to Write Software&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//./02-HITL-Human-AI-Collaboration-Why-AI-Code-Generation-Still-Needs-Human-Oversight.md"&gt;HITL Human-AI Collaboration: Why AI Code Generation Still Needs Human Oversight&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//./04-Multi-Agent-Architecture-Why-One-AI-Isnt-Enough.md"&gt;Multi-Agent Architecture: Why One AI Isn't Enough&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>openai</category>
      <category>cowork</category>
      <category>aiops</category>
    </item>
    <item>
      <title>HITL Human-AI Collaboration: Why AI Code Generation Still Needs Human Oversight</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Sun, 25 Jan 2026 10:13:04 +0000</pubDate>
      <link>https://dev.to/sopaco/hitl-human-ai-collaboration-why-ai-code-generation-still-needs-human-oversight-13n0</link>
      <guid>https://dev.to/sopaco/hitl-human-ai-collaboration-why-ai-code-generation-still-needs-human-oversight-13n0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine this scenario: You tell AI "Help me write a user login feature," and within seconds, AI generates a large amount of code. Sounds efficient, right?&lt;/p&gt;

&lt;p&gt;But here's the question: Is this code secure? Does it meet your requirements? Are there potential security vulnerabilities? Does it follow best practices?&lt;/p&gt;

&lt;p&gt;If you fully trust AI and directly deploy this code to production, it could have serious consequences. This is why even with powerful AI, we still need human oversight.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HITL (Human-in-the-Loop, human-AI collaboration)&lt;/strong&gt; isn't just a simple confirmation dialog—it's a thoughtful design philosophy that finds a balance between automation efficiency and output quality.&lt;/p&gt;

&lt;p&gt;In this article, I'll explore HITL's application in Cowork Forge in depth, looking at why human verification is needed, how to design effective HITL mechanisms, and best practices in actual use.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Credibility Issue of AI-Generated Content
&lt;/h2&gt;

&lt;p&gt;Before discussing HITL, we need to understand why AI-generated content needs human verification.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI's Limitations
&lt;/h3&gt;

&lt;p&gt;Although Large Language Models (LLMs) excel at code generation, they still have some inherent limitations.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;hallucination problems&lt;/strong&gt;. AI may produce "hallucinations"—generating content that looks reasonable but is actually incorrect. In code generation, this might manifest as calling non-existent APIs or libraries, using incorrect syntax or semantics, or generating code that looks correct but has logic errors. For example, AI might generate &lt;code&gt;let result = user.authenticate(password);&lt;/code&gt; but the &lt;code&gt;authenticate&lt;/code&gt; method might not exist at all.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;insufficient context understanding&lt;/strong&gt;. AI's context window is limited. It may not fully understand the entire project's context, leading to generated code that's inconsistent with existing code style, ignores project conventions and standards, or doesn't consider interactions with other modules. Imagine AI generating new code without knowing the project already has a common logging module, so it implements its own logging functionality, resulting in inconsistent code style.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;lack of domain knowledge&lt;/strong&gt;. AI's training data is public code repositories, so it may lack expertise in specific domains, such as industry-specific compliance requirements, company internal coding standards, or specific business logic complexity. For example, when developing a financial trading system, AI might not understand PCI DSS compliance requirements, know company internal security standards, or have experience designing high-performance trading systems.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;inability to make complex decisions&lt;/strong&gt;. Certain decisions require human judgment and experience, such as technology selection trade-offs, architecture design compromises, and security policy formulation. AI may not understand the complex considerations behind these decisions. For example, when selecting a database, AI might only consider performance factors while ignoring team technology stack, operational costs, data migration difficulty, and other multi-dimensional trade-offs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Risks of Full Automation
&lt;/h3&gt;

&lt;p&gt;If we fully trust AI and skip human verification, it could bring serious risks.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;security vulnerabilities&lt;/strong&gt;. AI-generated code may contain SQL injection, XSS attacks, permission bypass, sensitive information leakage, and other security vulnerabilities. Once exploited, the consequences could be disastrous. For example, AI-generated query code might not use parameterized queries, leading to SQL injection vulnerabilities.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;quality issues&lt;/strong&gt;. Code quality might not meet standards, such as performance problems, poor maintainability, insufficient test coverage, improper error handling. These issues increase subsequent maintenance costs. For example, AI-generated code might not consider concurrent access, leading to performance bottlenecks.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;business logic errors&lt;/strong&gt;. AI might misunderstand business requirements, leading to feature implementation that doesn't meet expectations, improper handling of edge cases, or incorrect understanding of business rules. This causes the product to fail to meet user needs. For example, AI might misunderstand the requirement "users can delete their own tasks" and think administrators can also delete users' tasks.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;compliance issues&lt;/strong&gt;. It might violate industry regulations or company policies, such as insufficient data privacy protection, missing audit logs, improper access control. These issues could lead to legal risks. For example, AI-generated user registration functionality might not record when and how users consented to terms, violating privacy regulations like GDPR.&lt;/p&gt;

&lt;h3&gt;
  
  
  HITL Design Philosophy
&lt;/h3&gt;

&lt;p&gt;The core philosophy of HITL is: introduce human verification at key decision points to ensure the quality and controllability of AI-generated content.&lt;/p&gt;

&lt;p&gt;This doesn't mean humans need to participate in every stage, but rather verify at key, high-impact decision points. This design philosophy is based on balancing efficiency and quality—automate repetitive, standardized tasks, and verify key decisions and complex logic manually, maintaining high efficiency while ensuring quality.&lt;/p&gt;

&lt;p&gt;At the same time, it reflects gradual trust building—start with small tasks to build trust in AI, gradually improve AI reliability through human verification, and gradually reduce human intervention based on trust.&lt;/p&gt;

&lt;p&gt;More importantly, it retains control—humans retain control over key decisions, AI serves as an assistant rather than a decision-maker, and can intervene and adjust when needed.&lt;/p&gt;

&lt;p&gt;Finally, it establishes a learning and feedback loop—collect feedback through human verification, improve AI behavior and output quality, and establish a continuous improvement mechanism.&lt;/p&gt;




&lt;h2&gt;
  
  
  Identifying Key Decision Points
&lt;/h2&gt;

&lt;p&gt;So which stages need human verification? Not all stages require human intervention—we need to identify key decision points.&lt;/p&gt;

&lt;h3&gt;
  
  
  Characteristics of Key Decision Points
&lt;/h3&gt;

&lt;p&gt;Whether a decision point needs human verification depends on several factors.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;scope of impact&lt;/strong&gt;. If this decision affects multiple modules or stages, it needs human verification; if the scope of impact is small, AI can be trusted. For example, modifying a PRD affects subsequent design, coding, testing, and other stages, so it needs human verification. But optimizing a function's internal implementation has a small scope of impact, so AI can be trusted.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;reversibility&lt;/strong&gt;. If a decision is irreversible or difficult to reverse, it needs human verification; if it can be easily rolled back, AI can be trusted. For example, deleting a core database table is hard to reverse once executed, so it needs human verification. But adding a new function can be easily deleted, so AI can be trusted.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;complexity&lt;/strong&gt;. If a decision involves complex logic or trade-offs, it needs human verification; if it's a simple, clear choice, AI can be trusted. For example, technology selection involves trade-offs across performance, cost, team skills, and other factors, so it needs human verification. But choosing which sorting algorithm to use can be automatically selected based on data characteristics, so AI can be trusted.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;risk level&lt;/strong&gt;. If decision failure leads to serious consequences, it needs human verification; if the risk is controllable, AI can be trusted. For example, deploying to production might cause service interruption if it fails, so it needs human verification. But running unit tests only requires fixing bugs if they fail, so the risk is controllable and AI can be trusted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Verification Points in Cowork Forge
&lt;/h3&gt;

&lt;p&gt;Based on the above principles, Cowork Forge sets human verification at several key nodes.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Requirements Collection Confirmation&lt;/strong&gt; is the first verification point. Requirements are the foundation of the entire development process—if misunderstood, all subsequent work will deviate. AI might misunderstand the user's true intent, inaccurate requirement scoping leads to development scope creep. So verification is needed to confirm whether AI correctly understands the core goal, whether the functional scope is accurate, whether user roles are correctly identified, and whether constraints are complete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PRD Confirmation&lt;/strong&gt; is the second verification point. The PRD is the blueprint for product development, directly affecting subsequent technical design and implementation. AI might miss important requirements or acceptance criteria, and requirement priorities might be unreasonable. So verification is needed to confirm whether functional requirements are complete, whether user stories are clear, whether acceptance criteria are testable, and whether non-functional requirements are thoroughly considered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design Confirmation&lt;/strong&gt; is the third verification point. Technical design determines the system's architecture and implementation approach. AI might choose an inappropriate technology stack, and the architecture design might not match the project's actual situation. So verification is needed to confirm whether technology stack selection is reasonable, whether architecture design is feasible, whether component division is reasonable, and whether the data model is correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Plan Confirmation&lt;/strong&gt; is the fourth verification point. The code plan determines which files will be modified. AI might miss files that need modification or include files that shouldn't be modified. So verification is needed to confirm the list of files to create, the list of files to modify, the change description for each file, and whether the change order is reasonable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trigger Conditions for Verification Points
&lt;/h3&gt;

&lt;p&gt;HITL verification point triggers aren't fixed but dynamically determined based on conditions.&lt;/p&gt;

&lt;p&gt;For example, in the PRD generation stage, if AI's confidence is below 0.8, human verification is triggered. In the technical design stage, if complexity reaches advanced level, human verification is triggered. In the coding stage, if confidence is below 0.7 or complexity reaches intermediate level, human verification is triggered. In the check stage, human verification usually isn't triggered because this is an automated verification process.&lt;/p&gt;

&lt;p&gt;The benefit of this dynamic trigger mechanism is: for simple, clear tasks, human verification can be skipped to improve efficiency; for complex, uncertain tasks, human verification is mandatory to ensure quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Actual Case Analysis: Consequences of Wrong Decisions
&lt;/h3&gt;

&lt;p&gt;Let's look at an actual case to see what happens if human verification is skipped.&lt;/p&gt;

&lt;p&gt;Suppose you're developing a payment system. AI generates a PRD that only includes two features: users can pay with credit cards and support refund operations, but misses key security requirements like PCI DSS compliance, transaction logging and auditing, and risk control rules.&lt;/p&gt;

&lt;p&gt;If you develop directly based on this PRD, the system might have serious security vulnerabilities, could lead to user financial loss, and might violate industry regulations. This is why human verification is so important at the PRD confirmation stage—humanly review the PRD, discover missing security requirements, and require AI to supplement relevant security requirements.&lt;/p&gt;

&lt;p&gt;This case tells us that while AI is powerful, it may lack expertise in specific domains. In key domains like finance, healthcare, and security, human verification is particularly important.&lt;/p&gt;




&lt;h2&gt;
  
  
  HITL Mechanism Design Philosophy
&lt;/h2&gt;

&lt;p&gt;HITL isn't just a simple "confirm" button—it's a complete interaction mechanism that needs careful design.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not Just a Simple Confirmation Dialog
&lt;/h3&gt;

&lt;p&gt;Many systems' HITL mechanisms are just a simple confirmation dialog: "AI has completed PRD generation. Continue? [Cancel] [Confirm]"&lt;/p&gt;

&lt;p&gt;The limitations of this design are obvious: users don't know what content AI generated, can't modify the content, and lack contextual information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cowork Forge's HITL Design
&lt;/h3&gt;

&lt;p&gt;Cowork Forge's HITL mechanism is more comprehensive.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;content display&lt;/strong&gt;. It displays AI output in a clear, readable format, provides sufficient contextual information, and supports multiple output formats (Markdown, JSON, etc.). For example, when displaying a PRD, it uses Markdown format and includes product overview, functional requirements list, user stories and acceptance criteria, and non-functional requirements, with clear headings and structure for each section.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;editing support&lt;/strong&gt;. It allows users to directly edit AI output, supports external editor integration, and preserves edit history. For example, users can directly edit the PRD in the terminal or launch external editors like VS Code for editing. Edit history is preserved for easy user backtracking and comparison.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;regeneration&lt;/strong&gt;. If users aren't satisfied, they can request AI to regenerate, can provide feedback to guide AI on how to improve. For example, users can say "This PRD is missing user tagging functionality, please add it," and AI will regenerate the PRD based on this feedback.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;interaction flow&lt;/strong&gt;. It provides a complete interaction flow, allowing users to choose to confirm directly, need editing, request regeneration, or reject. Users can choose the most appropriate operation based on their judgment.&lt;/p&gt;

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

&lt;p&gt;This flowchart shows the complete HITL interaction flow. Users have multiple choices, and each choice has clear processing logic. This design gives users full control, allowing them to choose the most appropriate operation based on their judgment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Content Display and Interaction Experience Design
&lt;/h3&gt;

&lt;p&gt;Content display has several principles.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;clarity&lt;/strong&gt;. Use clear headings and structure, highlight important information, use appropriate formatting (tables, lists, code blocks). For example, when displaying technology stack selection, it not only lists the selected technologies but also explains the selection rationale and lists alternatives.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;completeness&lt;/strong&gt;. Display all relevant information, don't miss important details, provide contextual explanations. For example, when displaying code plans, it not only lists files to modify but also explains the change content and reason for each file.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;actionability&lt;/strong&gt;. Clearly tell users what they can do, provide operation guidance, explain the consequences of different operations. For example, it clearly prompts users that they can choose to confirm and continue, edit content, regenerate, or view more details.&lt;/p&gt;

&lt;p&gt;Interaction experience design also has several key points.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;responsiveness&lt;/strong&gt;. Quickly respond to user operations, provide real-time feedback, avoid long waits. For example, after users click the "edit" button, the editor launches immediately; after users finish editing, the system immediately reprocesses the content.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;undo capability&lt;/strong&gt;. Support undo operations, preserve operation history, allow rollback to previous states. For example, if users edit the PRD but later realize the edit was wrong, they can undo the edit and return to the previous version.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;smart suggestions&lt;/strong&gt;. Provide intelligent suggestions, predict user intent, reduce user operation steps. For example, if it detects users modified functional requirements in the PRD, it prompts whether technical design needs to be regenerated.&lt;/p&gt;

&lt;h3&gt;
  
  
  User Editing and Regeneration Support
&lt;/h3&gt;

&lt;p&gt;Cowork Forge supports integrating external editors, allowing users to conveniently edit AI output.&lt;/p&gt;

&lt;p&gt;The external editor integration workflow is: HITL controller writes content to a temporary file, launches external editor (like VS Code), user edits content in the editor, editor returns edited content, HITL controller submits modified content to agent, agent reprocesses, returns processing result, HITL controller displays result to user.&lt;/p&gt;

&lt;p&gt;If users aren't satisfied with AI output, they can request regeneration. The regeneration workflow is: user requests regeneration, HITL controller requests user feedback, user provides feedback, HITL controller analyzes feedback, submits feedback to agent, agent adjusts prompt, calls LLM to regenerate, LLM returns new content, agent returns new content, HITL controller compares old and new output, displays differences to user.&lt;/p&gt;

&lt;p&gt;This design gives users full control, allowing them to choose the most appropriate operation based on their judgment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices in Actual Use
&lt;/h2&gt;

&lt;p&gt;After understanding HITL's design principles, let's see how to efficiently perform human verification in actual use.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Efficiently Perform Human Verification
&lt;/h3&gt;

&lt;p&gt;First, &lt;strong&gt;preparation&lt;/strong&gt;. Before starting to use Cowork Forge, you need to prepare. Clarify requirements—before inputting requirements, first clarify your true requirements, write down key functional points and constraints, prepare relevant reference materials. Understand the project—understand the project's technology stack and architecture, understand the project's coding standards and conventions, understand the project's business logic. Configure environment—configure external editors (like VS Code), configure Git and version control, configure necessary development tools.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;verification strategy&lt;/strong&gt;. Don't try to verify all content at once, do it in stages. Quick scan—first quickly browse AI output to understand the overall structure. Key check—focus on checking key parts like core features and security requirements. Detailed review—conduct detailed reviews of important parts. Cross-verify—compare AI output with original requirements.&lt;/p&gt;

&lt;p&gt;Using a checklist is also a good approach. Prepare a checklist for each verification stage to ensure no important check items are missed.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;editing techniques&lt;/strong&gt;. Use external editors—leverage editor syntax highlighting and auto-completion, use editor search and replace functionality, leverage editor version control integration. Preserve context—preserve original content when modifying for easy comparison, add comments explaining modification reasons, preserve modification history for easy backtracking. Progressive modification—first make large structural adjustments, then detail modifications, finally format adjustments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Problems and Solutions
&lt;/h3&gt;

&lt;p&gt;In actual use, you might encounter some common problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem 1: AI-generated content doesn't meet expectations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Possible causes include unclear requirement description, insufficient AI context information, or AI capability limitations.&lt;/p&gt;

&lt;p&gt;Solutions include re-describing requirements (use clearer, more specific language to describe requirements), providing more context (provide more background information and reference materials), direct editing (manually modify AI output), providing feedback (tell AI what's wrong and request regeneration).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem 2: AI misses important requirements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Possible causes include incomplete requirement description, AI not considering all scenarios, or AI training data lacking similar requirements.&lt;/p&gt;

&lt;p&gt;Solutions include supplementing requirements (manually add missing requirements), providing examples (provide similar feature examples), using checklists (use requirement checklists to ensure nothing is missed).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem 3: AI chooses inappropriate technology stack&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Possible causes include AI not understanding project technology constraints, AI training data biased toward certain technology stacks, or AI not considering team technical capabilities.&lt;/p&gt;

&lt;p&gt;Solutions include clarifying technology constraints (explicitly state technology constraints in requirements), providing technology stack suggestions (directly tell AI which technology stack to use), manual modification (manually modify technology stack selection).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem 4: AI output format doesn't meet requirements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Possible causes include AI not understanding project format standards, or AI training data format inconsistency.&lt;/p&gt;

&lt;p&gt;Solutions include providing format templates (provide standard format templates), manually adjusting format (manually adjust output format), configuring format rules (specify format rules in configuration files).&lt;/p&gt;

&lt;h3&gt;
  
  
  HITL Application in Team Collaboration Scenarios
&lt;/h3&gt;

&lt;p&gt;In team collaboration scenarios, HITL mechanisms need to support multi-user collaboration.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;role division&lt;/strong&gt;. Different team members are responsible for different verification stages: product manager responsible for requirements collection and PRD verification, technical lead responsible for technical design and code plan verification, development engineer responsible for code review.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;collaboration process&lt;/strong&gt;. Requirements collection → product manager verification → PRD generation → product manager verification → technical design → technical lead verification → code planning → development engineer verification → code generation → code review → check verification.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;collaboration tools&lt;/strong&gt;. Tools supporting team collaboration include comments and discussion (support adding comments on content), version management (support comparing different versions), permission control (different roles have different permissions), notification mechanism (notify relevant personnel for verification).&lt;/p&gt;

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

&lt;p&gt;This sequence diagram shows the HITL process in team collaboration scenarios. Different roles are responsible for different verification stages, ensuring each stage has appropriate personnel for verification.&lt;/p&gt;




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

&lt;p&gt;HITL (Human-in-the-Loop) is one of Cowork Forge's core design philosophies, finding a balance between automation efficiency and output quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  HITL Value
&lt;/h3&gt;

&lt;p&gt;First, &lt;strong&gt;balance between efficiency and quality&lt;/strong&gt;. Automate repetitive tasks to improve efficiency, verify key decisions manually to ensure quality, maintaining high efficiency without sacrificing quality.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;gradual trust building&lt;/strong&gt;. Start with small tasks to build trust in AI, gradually improve AI reliability through human verification, gradually reduce human intervention based on trust.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;retaining control&lt;/strong&gt;. Humans retain control over key decisions, AI serves as an assistant rather than a decision-maker, can intervene and adjust when needed.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;learning and feedback&lt;/strong&gt;. Collect feedback through human verification, improve AI behavior and output quality, establish a continuous improvement loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Future Automation Level Evolution
&lt;/h3&gt;

&lt;p&gt;As AI technology develops, HITL mechanisms will also continue to evolve.&lt;/p&gt;

&lt;p&gt;Short-term, optimize HITL interaction experience, improve agent confidence judgment capability, reduce unnecessary verification stages.&lt;/p&gt;

&lt;p&gt;Medium-term, introduce automated testing and verification, establish agent behavior evaluation mechanisms, dynamically adjust verification strategies based on historical data.&lt;/p&gt;

&lt;p&gt;Long-term, achieve highly reliable AI, reduce human verification, establish complete AI trust systems, achieve deep AI-human collaboration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recommendations for Users
&lt;/h3&gt;

&lt;p&gt;First, &lt;strong&gt;don't skip human verification&lt;/strong&gt;. Even if AI output looks perfect, review it carefully. Human verification is a key link in ensuring quality.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;provide clear feedback&lt;/strong&gt;. If AI output doesn't meet expectations, provide clear feedback to help AI improve.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;establish verification habits&lt;/strong&gt;. Establish systematic verification habits, use checklists to ensure no important check items are missed.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;continuous learning and improvement&lt;/strong&gt;. Through using HITL, continuously learn and improve, increase verification efficiency and quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;HITL isn't distrust of AI capability, but reasonable use of AI capability. AI is a powerful tool, but it still needs human guidance and supervision.&lt;/p&gt;

&lt;p&gt;Through HITL mechanisms, we can enjoy the efficiency improvement brought by AI while ensuring output quality and controllability. This is the true meaning of human-AI collaboration.&lt;/p&gt;

&lt;p&gt;Future software development isn't AI replacing humans, but AI and humans collaborating deeply to create better software together.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Related Reading&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="//./01-From-Idea-to-Code-How-AI-Multi-Agents-Work-Like-a-Team-to-Write-Software.md"&gt;From Idea to Code: How an AI Multi-Agent System Works Like a Team to Write Software&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//./03-Incremental-Code-Updates-How-AI-Only-Modifies-Files-That-Need-Changing.md"&gt;Incremental Code Updates: How AI Only Modifies Files That Need Changing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//./04-Multi-Agent-Architecture-Why-One-AI-Isnt-Enough.md"&gt;Multi-Agent Architecture: Why One AI Isn't Enough&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>openai</category>
      <category>cowork</category>
      <category>ai</category>
      <category>aiops</category>
    </item>
    <item>
      <title>From Idea to Code: How an AI Multi-Agent System Works Like a Team to Write Software</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Sun, 25 Jan 2026 10:11:00 +0000</pubDate>
      <link>https://dev.to/sopaco/from-idea-to-code-how-an-ai-multi-agent-system-works-like-a-team-to-write-software-568h</link>
      <guid>https://dev.to/sopaco/from-idea-to-code-how-an-ai-multi-agent-system-works-like-a-team-to-write-software-568h</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcc6pfc2uis29yon2jf1u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcc6pfc2uis29yon2jf1u.png" alt=" " width="800" height="709"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cowork Forge - An open-source AI multi-agent development platform, serving as both an embeddable AI Coding engine and a standalone production-grade development tool. GitHub: &lt;a href="https://github.com/sopaco/cowork-forge" rel="noopener noreferrer"&gt;https://github.com/sopaco/cowork-forge&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you ever wondered what it would be like to have a virtual development team that could understand your ideas and automatically complete the entire process from requirements analysis to code delivery?&lt;/p&gt;

&lt;p&gt;This isn't science fiction—it's happening right now.&lt;/p&gt;

&lt;p&gt;Think about our daily development work. Aren't there always some repetitive tasks that give us headaches? When a requirement change comes in, you have to update the requirements document, then update the design document, modify the code, and update test cases... And you have to constantly communicate with product managers, designers, and test engineers throughout these stages. Time gets consumed bit by bit on these mechanical tasks, leaving little time for truly valuable creative work.&lt;/p&gt;

&lt;p&gt;Over the years, we've witnessed the rapid evolution of development tools. From IDE code completion, to intelligent coding assistants like GitHub Copilot, to today's AI Agents. But most of these tools still remain at the "assistance" level—they can help you write a few lines of code, but cannot understand the entire software development lifecycle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cowork Forge&lt;/strong&gt; attempts to break this limitation. It's not a simple code completion tool, but a complete software development automation platform. By coordinating 7 specialized AI agents, it collaborates like a real development team, transforming your ideas step by step into production-ready code.&lt;/p&gt;

&lt;p&gt;In this article, I'll take you deep into how Cowork Forge works, showing you how these AI agents divide and collaborate, and how it differs from existing AI development tools.&lt;/p&gt;




&lt;h2&gt;
  
  
  Traditional Development vs. AI Collaborative Development
&lt;/h2&gt;

&lt;p&gt;Before diving into Cowork Forge, let's look at the differences between traditional development patterns and AI collaborative development patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real Experience of Traditional Development Patterns
&lt;/h3&gt;

&lt;p&gt;The traditional software development process is something we're all familiar with. The product manager holds a requirements meeting, organizes the requirements document, and writes the PRD. The technical lead receives the PRD and starts architectural design, writing technical documentation. Developers receive the design document and start writing code. Testers receive the code and write test cases, executing tests. Operations personnel receive the code that passed tests and deploy it to production.&lt;/p&gt;

&lt;p&gt;This process sounds standardized, but in practice, there are many problems.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;too much manual work&lt;/strong&gt;. Every stage requires significant human involvement, and much of the work is repetitive. For example, formatting requirements documents, drawing design documents, writing test cases... While this work is important, it's truly time-consuming.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;high communication costs&lt;/strong&gt;. Team members need to communicate frequently, and information can easily get distorted during transmission. A product manager describes a requirement, the technical lead understands it as something else, and what the developer implements might be yet another thing. This "telephone game" is all too common in the development process.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;knowledge silos&lt;/strong&gt;. Requirements, design, and code are scattered across different people and documents, making it difficult to maintain consistency. When requirements change, you have to manually modify multiple stages—not only is it inefficient, but it's also easy to miss things.&lt;/p&gt;

&lt;h3&gt;
  
  
  Changes Brought by AI Collaborative Development
&lt;/h3&gt;

&lt;p&gt;AI collaborative development patterns thoroughly transform this process through agent automation and collaboration.&lt;/p&gt;

&lt;p&gt;In the requirements processing stage, AI can automatically structure your ideas and generate professional requirements documents. In the document generation stage, AI can automatically generate PRDs and design documents based on requirements. In the code generation stage, AI can plan and execute code changes. In the quality verification stage, AI can automate building, testing, and verification. In the change management stage, AI can intelligently identify the scope of impact and update only affected files.&lt;/p&gt;

&lt;p&gt;What are the core advantages of this pattern?&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;end-to-end automation&lt;/strong&gt;. The complete process from idea to delivery can be automated, greatly reducing manual intervention stages. You don't need to switch between multiple tools—all stage outputs are unified in storage and management.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;specialized division of labor&lt;/strong&gt;. Each agent focuses on a specific domain, providing specialized output. For example, the PRD agent focuses on product requirements and outputs professional PRD documents; the design agent focuses on technical architecture and applies design methods like the C4 model; the coding agent focuses on code generation and supports incremental updates; the check agent focuses on quality verification and automates building and testing.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;context sharing&lt;/strong&gt;. All agents share a unified context, ensuring consistency across all stages. When requirements change, AI can quickly identify the scope of impact and update relevant content.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;rapid response&lt;/strong&gt;. Compared to traditional patterns, AI collaborative development responds much faster. When requirements change, there's no need to manually modify multiple stages—AI can automatically handle most of the work.&lt;/p&gt;




&lt;h2&gt;
  
  
  Role Division Among the 7 Agents
&lt;/h2&gt;

&lt;p&gt;The core of Cowork Forge is 7 specialized AI agents, each responsible for different stages of software development. They collaborate like a real development team, each performing their own duties.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overall Architecture
&lt;/h3&gt;

&lt;p&gt;Cowork Forge adopts a layered architecture design, divided from top to bottom into the agent collaboration layer, orchestration layer, and infrastructure layer.&lt;/p&gt;

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

&lt;p&gt;In this architecture, the orchestration layer is responsible for coordinating agent execution, while the infrastructure layer provides foundational capabilities including tool support, verification security, data management, and interaction control. The benefit of this layered design is clear responsibility separation—the orchestration layer focuses on process control, the agent layer focuses on business logic, and the infrastructure layer provides common capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agent Collaboration Process
&lt;/h3&gt;

&lt;p&gt;The 7 agents collaborate according to a predefined process, with each agent passing results to the next agent after completing its own task. This process isn't simple linear execution, but an intelligent process with feedback loops.&lt;/p&gt;

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

&lt;p&gt;An important feature of this process is &lt;strong&gt;intelligent rollback&lt;/strong&gt;. When the check stage discovers a problem, the feedback agent doesn't simply request re-execution. Instead, it intelligently analyzes the root cause of the problem and determines which stage to re-execute from. If the problem is a misunderstanding of requirements, it returns to the PRD stage; if it's a design problem, it returns to the design stage; if it's a code implementation problem, it returns to the coding stage. This intelligent rollback mechanism greatly improves problem-solving efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Responsibilities of Each Agent
&lt;/h3&gt;

&lt;p&gt;Let's look at what each of these agents does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements Collection Agent&lt;/strong&gt; is the first to take the stage. Its task is to transform your ideas—which might be just a sentence like "I want to build a task management app"—into a structured requirements specification. This is like an experienced product manager who can extract real requirements from your simple description. It needs to understand vague requirement descriptions, identify key requirement points, and even ask clarification questions through the HITL mechanism.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PRD Agent&lt;/strong&gt;, after receiving the structured requirements specification, generates a complete Product Requirements Document. It needs to transform requirements into a professional PRD format, identify dependencies between requirements, and perform priority sorting. This is like a professional product manager who can write clear, complete product documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design Agent&lt;/strong&gt; generates technical architecture and design solutions based on the PRD. It needs to apply professional architecture models, make technology selection decisions, and apply appropriate architecture patterns. This is like a senior technical lead who can design reasonable technical solutions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coding Stage Agent&lt;/strong&gt; is the most complex agent, responsible for planning and executing code changes and supporting incremental updates. It contains three sub-components internally: CodePlanner is responsible for generating code change plans, CodeExecutor is responsible for executing code generation, and CodeUpdater is responsible for supporting incremental code updates. It needs to analyze project structure, plan code changes, support incremental updates, and safely execute code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check Agent&lt;/strong&gt; is responsible for verifying code quality and project build status. It needs to detect project types (supporting Rust, Python, JavaScript/TypeScript), automate building and testing, analyze errors, and calculate requirements coverage. It generates a check report containing build results, test results, error analysis, quality metrics, etc.&lt;/p&gt;

&lt;p&gt;If the check discovers problems, the &lt;strong&gt;Feedback Agent&lt;/strong&gt; takes the stage. It's responsible for analyzing user feedback and determining the scope of re-execution. It analyzes feedback content, identifies the scope of impact, and intelligently decides which stage to re-execute. It generates feedback artifacts containing change requirement analysis, re-execution stage decisions, and modification suggestions.&lt;/p&gt;

&lt;p&gt;Finally, there's the &lt;strong&gt;Delivery Agent&lt;/strong&gt;. It's responsible for generating a delivery report that summarizes the entire development process. It aggregates information from all stages to generate a complete delivery report containing an implementation summary, requirements coverage, quality metrics, follow-up recommendations, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Do We Need Multiple Agents?
&lt;/h3&gt;

&lt;p&gt;You might ask: Why can't one all-powerful AI complete all the work? There are several reasons.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;specialized capabilities&lt;/strong&gt;. Different stages of software development require different professional knowledge and skills. Requirements analysis requires product thinking and user perspective, technical design requires architecture experience and engineering practice, code generation requires programming language and framework knowledge, and test verification requires quality assurance experience. Through specialized division of labor, each agent can provide higher quality output in its domain.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;single responsibility&lt;/strong&gt;. The single responsibility principle applies not only to code design but also to agent design. Each agent focuses on a clear responsibility, making agent behavior more predictable, errors easier to locate and fix, and agents easier to test and verify.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;scalability&lt;/strong&gt;. Multi-agent architecture has good scalability. You can easily add new agents, such as a performance optimization agent, a security audit agent. Each agent can be independently optimized and upgraded, and agents can be dynamically loaded as plugins.&lt;/p&gt;

&lt;p&gt;Fourth, &lt;strong&gt;parallel processing&lt;/strong&gt;. The work of certain agents can be performed in parallel, improving overall efficiency. For example, document generation and code planning can be parallelized, and code generation for multiple files can be parallelized.&lt;/p&gt;




&lt;h2&gt;
  
  
  End-to-End Workflow Experience
&lt;/h2&gt;

&lt;p&gt;Having discussed so much theory, let's look at how Cowork Forge completes the entire development process from idea to code through a real case.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Real Scenario
&lt;/h3&gt;

&lt;p&gt;Suppose you have an idea: "I want to build a task management REST API that supports creating tasks, updating task status, and querying task lists."&lt;/p&gt;

&lt;p&gt;With just this simple sentence, Cowork Forge can start working.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complete Workflow
&lt;/h3&gt;

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

&lt;p&gt;This sequence diagram shows the complete end-to-end workflow. You can see that each agent has its own responsibilities, and they transfer data through artifacts. The HITL controller intervenes at key nodes, letting users confirm AI outputs to ensure quality and controllability.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Actually Happens at Each Stage
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Stage 1: Requirements Collection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You input the sentence "I want to build a task management REST API that supports creating tasks, updating task status, and querying task lists."&lt;/p&gt;

&lt;p&gt;The Requirements Collection Agent starts working. It calls the LLM to structure your sentence into an IdeaSpec. It identifies that the core goal is "build a task management REST API," the functional scope includes "create tasks," "update task status," "query task lists," the user role is "regular user," and constraints include "use RESTful architecture," "support concurrent access," "data persistence."&lt;/p&gt;

&lt;p&gt;Then through the HITL mechanism, it displays this structured requirements specification to you for confirmation. After you confirm, this stage is complete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 2: PRD Generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After receiving the IdeaSpec, the PRD Agent starts generating the Product Requirements Document.&lt;/p&gt;

&lt;p&gt;It generates a complete PRD containing product overview, functional requirements list, user stories and acceptance criteria, and non-functional requirements. For example, for the "create task" function, it writes the function description, inputs (task title required, task description optional, task status defaults to "pending"), and outputs (task ID and task information).&lt;/p&gt;

&lt;p&gt;Similarly, it displays the PRD to you through the HITL mechanism for confirmation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 3: Technical Design&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After receiving the PRD, the Design Agent starts generating technical architecture and design solutions.&lt;/p&gt;

&lt;p&gt;It generates a design document containing system architecture design (using C4 model), technology stack selection recommendations, component and module division, data model design, and interface definitions. For example, it selects Rust as the development language, Actix-web as the web framework, SQLite as the database, and Diesel as the ORM. It designs the Task data model, defines the TaskStatus enum, and plans the API interfaces.&lt;/p&gt;

&lt;p&gt;Similarly, it displays the design document to you through the HITL mechanism for confirmation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 4: Coding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After receiving the design document, the Coding Stage Agent starts planning and executing code changes.&lt;/p&gt;

&lt;p&gt;It first analyzes the project structure and generates a code change plan. For example, it plans the files that need to be created: src/main.rs, src/models.rs, src/db.rs, src/handlers.rs, src/routes.rs.&lt;/p&gt;

&lt;p&gt;Then it generates the actual code. For example, in src/models.rs, it generates the Task struct and NewTask struct, including all necessary fields and serialization markers.&lt;/p&gt;

&lt;p&gt;Similarly, it displays the code plan to you through the HITL mechanism for confirmation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 5: Check&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After receiving the code, the Check Agent starts verifying code quality and project build status.&lt;/p&gt;

&lt;p&gt;It runs builds and tests, generating a check report. The report shows build status (success or failure), test results (pass or fail), error analysis, and quality metrics (code coverage, cyclomatic complexity, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 6: Delivery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After receiving artifacts from all stages, the Delivery Agent generates a delivery report.&lt;/p&gt;

&lt;p&gt;This report summarizes the entire development process, including implementation summary, requirements coverage, quality metrics, and follow-up recommendations. For example, it tells you that all functional requirements have been implemented, build status passed, test pass rate is 100%, code coverage is 85%, and suggests adding user authentication and authorization, implementing task tags and categorization features in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Human Verification at Key Nodes
&lt;/h3&gt;

&lt;p&gt;You may have noticed that there are several key nodes in the entire workflow that require your human verification.&lt;/p&gt;

&lt;p&gt;Requirements collection confirmation, PRD confirmation, design confirmation, code plan confirmation—these nodes all require you to review AI outputs and confirm they're correct before continuing.&lt;/p&gt;

&lt;p&gt;This HITL (Human-in-the-Loop) mechanism ensures the quality and controllability of AI-generated content, finding a balance between automation efficiency and human control. You don't completely lose control—instead, you still have a say at key decision points.&lt;/p&gt;




&lt;h2&gt;
  
  
  Differentiation from Competitors
&lt;/h2&gt;

&lt;p&gt;There are already many AI development tools on the market. What makes Cowork Forge unique compared to them?&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Capability Comparison
&lt;/h3&gt;

&lt;p&gt;Let's look at the comparison between Cowork Forge and several mainstream tools.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Cowork Forge&lt;/th&gt;
&lt;th&gt;GitHub Copilot&lt;/th&gt;
&lt;th&gt;Cursor AI&lt;/th&gt;
&lt;th&gt;Aider&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;End-to-End Workflow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Complete (Idea→Delivery)&lt;/td&gt;
&lt;td&gt;❌ Only code completion&lt;/td&gt;
&lt;td&gt;❌ Focused on code editing&lt;/td&gt;
&lt;td&gt;❌ Only code assistance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-Agent Architecture&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 7 specialized agents&lt;/td&gt;
&lt;td&gt;❌ Single model&lt;/td&gt;
&lt;td&gt;❌ Single model&lt;/td&gt;
&lt;td&gt;❌ Single model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PRD Generation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Automated&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Technical Design&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ C4 architecture docs&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Incremental Updates&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Intelligent incremental analysis&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;td&gt;❌ Limited&lt;/td&gt;
&lt;td&gt;❌ Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-Language Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Rust, Python, JS/TS&lt;/td&gt;
&lt;td&gt;✅ Multiple languages&lt;/td&gt;
&lt;td&gt;✅ Multiple languages&lt;/td&gt;
&lt;td&gt;✅ Multiple languages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Human-AI Collaboration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Key decision points&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;td&gt;❌ Limited&lt;/td&gt;
&lt;td&gt;❌ Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Automated Verification&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Build/test integration&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Security Checks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Multi-layer security&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;td&gt;❌ Basic&lt;/td&gt;
&lt;td&gt;❌ Basic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Artifact Storage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Versioned artifacts&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;td&gt;❌ N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Open Source&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ MIT License&lt;/td&gt;
&lt;td&gt;❌ Proprietary&lt;/td&gt;
&lt;td&gt;❌ Proprietary&lt;/td&gt;
&lt;td&gt;✅ MIT License&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Self-Hosted&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Local execution&lt;/td&gt;
&lt;td&gt;❌ Cloud only&lt;/td&gt;
&lt;td&gt;❌ Cloud only&lt;/td&gt;
&lt;td&gt;✅ Local execution&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This comparison table clearly shows Cowork Forge's differentiated advantages. Unlike code completion tools that only assist with writing single lines of code, Cowork Forge manages the entire software development process—from initial idea collection to final delivery. This comprehensive approach ensures consistency and traceability across all stages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Differentiation Advantages
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Complete Development Lifecycle&lt;/strong&gt; is the first differentiation advantage of Cowork Forge. Unlike code completion tools that only assist with writing single lines of code, Cowork Forge manages the entire software development process—from initial idea collection to final delivery. This comprehensive approach ensures consistency and traceability across all stages. You don't need to switch between multiple tools—all stage outputs are unified in storage and management. When requirements change, you can trace the impact to all related stages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-Agent Collaboration&lt;/strong&gt; is the second differentiation advantage. Cowork Forge's 7 specialized agents collaborate like a real development team, with each agent bringing professional expertise in its domain. The PRD agent focuses on product requirements and outputs professional PRD documents; the design agent focuses on technical architecture and applies design methods like the C4 model; the coding agent focuses on code generation and supports incremental updates; the check agent focuses on quality verification and automates building and testing. This specialized division of labor ensures output quality at each stage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Human-AI Collaboration Verification&lt;/strong&gt; is the third differentiation advantage. Key outputs require human confirmation before proceeding, ensuring accurate requirement capture, reasonable technical decisions, and safe code changes. This balance between automation and human control distinguishes Cowork Forge from fully autonomous tools. You can control AI outputs, avoid erroneous decisions, intervene and adjust at key nodes, and retain control over the development process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Incremental Code Updates&lt;/strong&gt; is the fourth differentiation advantage. When requirements or designs change, Cowork Forge intelligently identifies affected files and only updates necessary content—preserving your customizations and avoiding full regeneration. This means it won't overwrite code you've manually modified, changes are more precise, unnecessary modifications are reduced, and development efficiency is improved, especially in iterative development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Built-in Security&lt;/strong&gt; is the fifth differentiation advantage. Multi-layer security checks prevent dangerous command execution (rm -rf, sudo, etc.), unauthorized file system access, malicious code injection, and resource exhaustion. This means you can confidently let AI execute code operations without worrying about AI deleting important files or executing dangerous commands, providing enterprise-level security guarantees.&lt;/p&gt;

&lt;h3&gt;
  
  
  Applicable Scenario Analysis
&lt;/h3&gt;

&lt;p&gt;Cowork Forge is best suited for scenarios including: rapid new project startup (from idea to prototype, quickly validating product concepts, automatically generating project foundation and core features), incremental feature development (adding new features to existing projects, rapid response to requirement changes), small to medium projects (small team size, need to improve development efficiency, moderate project complexity suitable for automation), and documentation-driven development (need complete PRDs, design documents, emphasizing consistency between requirements and design).&lt;/p&gt;

&lt;p&gt;Less suitable scenarios include: highly customized complex systems (complex business logic requiring many human decisions, special technology stacks where AI lacks relevant knowledge), creative design (UI/UX design requiring human creativity and aesthetics, product innovation requiring human insight), and systems with extreme performance requirements (performance-critical code requiring deep optimization, fine-grained resource management).&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary and Outlook
&lt;/h2&gt;

&lt;p&gt;Cowork Forge represents a new paradigm for AI-driven software development automation. Through multi-agent collaboration, it achieves end-to-end automation from idea to code, while retaining human control over key decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Value Review
&lt;/h3&gt;

&lt;p&gt;Cowork Forge's core value lies in: end-to-end automation (complete process automation from requirements collection to code delivery), specialized division of labor (7 agents each performing their duties, providing specialized output), human-AI collaboration (human verification at key decision points ensuring quality and controllability), incremental updates (intelligent scope identification avoiding full regeneration), and security-first (multi-layer security checks ensuring safe code execution).&lt;/p&gt;

&lt;h3&gt;
  
  
  Future Evolution Directions
&lt;/h3&gt;

&lt;p&gt;Cowork Forge continues to evolve, with future development directions including: distributed architecture (supporting multi-machine collaboration for complex projects, improving concurrent processing capabilities), agent learning capabilities (optimizing agent behavior based on historical sessions, personalized recommendations and optimization), multi-modal support (supporting more input forms like images, audio, supporting more output types like UI prototypes), team collaboration features (multiple users participating in the same project simultaneously, real-time collaboration and conflict resolution), and more agents (performance optimization agent, security audit agent, documentation generation agent).&lt;/p&gt;

&lt;h3&gt;
  
  
  Recommendations for Developers
&lt;/h3&gt;

&lt;p&gt;If you're considering using Cowork Forge, here are some recommendations: start with small projects (try it on simple projects first, get familiar with the workflow, gradually apply to more complex projects), make full use of HITL (don't skip human verification steps, carefully review AI outputs at key nodes), understand agent capability boundaries (know what each agent can and cannot do, use the right tool for the right scenario), maintain code quality (don't fully rely on AI, still perform code reviews, maintain good coding habits and standards), and provide feedback (if AI output doesn't meet expectations, provide detailed feedback to help improve agent behavior).&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;AI is changing the way software is developed, and Cowork Forge is an important attempt in this transformation. It's not meant to replace developers, but to become a capable assistant helping us complete repetitive work more efficiently, allowing us to focus on more valuable creative work.&lt;/p&gt;

&lt;p&gt;Just as IDEs won't replace developers, GitHub Copilot won't replace developers, AI Agents won't replace developers either. They're just tools that help us improve efficiency, enabling us to do more.&lt;/p&gt;

&lt;p&gt;The future belongs to developers who can skillfully use AI tools. Let's embrace this new era together.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Related Reading&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="//./02-HITL-Human-AI-Collaboration-Why-AI-Code-Generation-Still-Needs-Human-Oversight.md"&gt;HITL Human-AI Collaboration: Why AI Code Generation Still Needs Human Oversight&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//./03-Incremental-Code-Updates-How-AI-Only-Modifies-Files-That-Need-Changing.md"&gt;Incremental Code Updates: How AI Only Modifies Files That Need Changing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//./04-Multi-Agent-Architecture-Why-One-AI-Isnt-Enough.md"&gt;Multi-Agent Architecture: Why One AI Isn't Enough&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cowork</category>
      <category>openai</category>
    </item>
    <item>
      <title>Design and Implementation of AI Memory System Evaluation Framework: How to Scientifically Measure Memory Quality</title>
      <dc:creator>Sopaco</dc:creator>
      <pubDate>Sun, 28 Dec 2025 11:34:15 +0000</pubDate>
      <link>https://dev.to/sopaco/design-and-implementation-of-ai-memory-system-evaluation-framework-how-to-scientifically-measure-481l</link>
      <guid>https://dev.to/sopaco/design-and-implementation-of-ai-memory-system-evaluation-framework-how-to-scientifically-measure-481l</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;Building an AI Agent memory system is just the first step; scientifically evaluating its performance, accuracy, and reliability is equally important. &lt;a href="https://github.com/sopaco/cortex-mem" rel="noopener noreferrer"&gt;&lt;strong&gt;Cortex Memory&lt;/strong&gt;&lt;/a&gt; includes a complete evaluation framework supporting recall evaluation, effectiveness evaluation, performance evaluation, and other testing scenarios. This article provides an in-depth analysis of the evaluation framework's design philosophy, core implementation, and how to use it to validate and optimize memory system performance.&lt;/p&gt;

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




&lt;h2&gt;
  
  
  1. Problem Background: The Importance of Evaluation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 Why an Evaluation Framework is Needed
&lt;/h3&gt;

&lt;p&gt;The quality of a memory system directly impacts AI Agent performance, but how do we quantify this quality?&lt;/p&gt;

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

&lt;h3&gt;
  
  
  1.2 Core Evaluation Metrics
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric Category&lt;/th&gt;
&lt;th&gt;Specific Metrics&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Recall&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Precision@K, Recall@K, MAP, NDCG&lt;/td&gt;
&lt;td&gt;Measure retrieval accuracy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Effectiveness&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fact extraction accuracy, classification correctness, deduplication accuracy&lt;/td&gt;
&lt;td&gt;Measure processing quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Latency, throughput, memory usage&lt;/td&gt;
&lt;td&gt;Measure system efficiency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reliability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Error rate, availability, consistency&lt;/td&gt;
&lt;td&gt;Measure stability&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  1.3 Evaluation Challenges
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Lack of standards&lt;/strong&gt;: No unified evaluation standards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data dependency&lt;/strong&gt;: Requires high-quality test datasets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scenario diversity&lt;/strong&gt;: Different application scenarios focus on different metrics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous change&lt;/strong&gt;: Re-evaluation needed after system optimization&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  2. Evaluation Framework Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Overall Architecture
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  2.2 Core Components
&lt;/h3&gt;

&lt;h4&gt;
  
  
  2.2.1 Dataset Manager
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;DatasetManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dataset&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Dataset&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;test_cases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DatasetMetadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;TestCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&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;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;expected_results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ExpectedResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TestCaseMetadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ExpectedResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;memory_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;relevance_score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;DatasetType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Recall&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// Recall testing&lt;/span&gt;
    &lt;span class="n"&gt;Effectiveness&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Effectiveness testing&lt;/span&gt;
    &lt;span class="n"&gt;Performance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// Performance testing&lt;/span&gt;
    &lt;span class="n"&gt;Mixed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// Mixed testing&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2.2.2 Evaluator Interface
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[async_trait]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;Evaluator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Sync&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;fn&lt;/span&gt; &lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Dataset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EvaluationResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;fn&lt;/span&gt; &lt;span class="nf"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MetricDefinition&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;EvaluationResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;evaluator_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;dataset_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MetricValue&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EvaluationDetails&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Utc&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;MetricValue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;EvaluationDetails&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;test_cases_passed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;test_cases_total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EvaluationError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;warnings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EvaluationWarning&lt;/span&gt;&lt;span class="o"&gt;&amp;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;h2&gt;
  
  
  3. Recall Evaluation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Evaluation Metrics
&lt;/h3&gt;

&lt;h4&gt;
  
  
  3.1.1 Precision@K
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;PrecisionAtK&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;PrecisionAtK&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ScoredMemory&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&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;retrieved&lt;/span&gt;&lt;span class="nf"&gt;.is_empty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.k&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;relevant_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;
            &lt;span class="nf"&gt;.filter&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="py"&gt;.memory.id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="nf"&gt;.count&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;relevant_count&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.k&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage example&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;precision_at_5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PrecisionAtK&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;precision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;precision_at_5&lt;/span&gt;&lt;span class="nf"&gt;.calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;relevant_ids&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.1.2 Recall@K
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;RecallAtK&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;RecallAtK&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ScoredMemory&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&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;relevant&lt;/span&gt;&lt;span class="nf"&gt;.is_empty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.k&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;retrieved_relevant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;
            &lt;span class="nf"&gt;.filter&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="py"&gt;.memory.id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="nf"&gt;.count&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;retrieved_relevant&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&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;h4&gt;
  
  
  3.1.3 Mean Average Precision (MAP)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;MeanAveragePrecision&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;MeanAveragePrecision&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;all_results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ScoredMemory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;all_relevant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;aps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;all_results&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&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;all_relevant&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&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;relevant&lt;/span&gt;&lt;span class="nf"&gt;.is_empty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.average_precision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;aps&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ap&lt;/span&gt;&lt;span class="p"&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;aps&lt;/span&gt;&lt;span class="nf"&gt;.is_empty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;aps&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.sum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;aps&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;average_precision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ScoredMemory&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;precision_sum&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="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;relevant_count&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="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&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;relevant&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.memory.id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;relevant_count&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;precision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;relevant_count&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;precision_sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;precision&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;relevant_count&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="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;precision_sum&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;relevant_count&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&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;h4&gt;
  
  
  3.1.4 Normalized Discounted Cumulative Gain (NDCG)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;NDCG&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;NDCG&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ScoredMemory&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dcg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.dcg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;idcg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.idcg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;relevant&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;idcg&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="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;dcg&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;idcg&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;dcg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ScoredMemory&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;dcg&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="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;relevance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.memory.id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&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;dcg&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;relevance&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;dcg&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;idcg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;sorted_relevance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="nf"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.cloned&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;sorted_relevance&lt;/span&gt;&lt;span class="nf"&gt;.sort_by&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="nf"&gt;.partial_cmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;idcg&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="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;relevance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;sorted_relevance&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;idcg&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;relevance&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;idcg&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;h3&gt;
  
  
  3.2 Recall Evaluator Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;RecallEvaluator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RecallEvaluatorConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;memory_manager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MemoryManager&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Clone)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;RecallEvaluatorConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;k_values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;similarity_thresholds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;max_results_per_query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[async_trait]&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Evaluator&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;RecallEvaluator&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;fn&lt;/span&gt; &lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Dataset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EvaluationResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;details&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EvaluationDetails&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;test_cases_passed&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;test_cases_total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="py"&gt;.test_cases&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;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;warnings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;// Calculate Precision and Recall for each K value&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.config.k_values&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;precision_values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;recall_values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&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;test_case&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="py"&gt;.test_cases&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.evaluate_test_case&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_case&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;precision&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;precision_values&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precision&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;recall_values&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="py"&gt;.test_cases_passed&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="p"&gt;}&lt;/span&gt;
                    &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="py"&gt;.errors&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EvaluationError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="n"&gt;test_case_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;test_case&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;&lt;span class="nf"&gt;.clone&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="n"&gt;e&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// Calculate averages&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;avg_precision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;precision_values&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.sum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;precision_values&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;avg_recall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recall_values&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.sum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;recall_values&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"precision@{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;MetricValue&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="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Precision@{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;avg_precision&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"score"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Average precision at K={}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&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="n"&gt;metrics&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"recall@{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;MetricValue&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="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Recall@{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;avg_recall&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"score"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Average recall at K={}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&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;span class="c1"&gt;// Calculate MAP and NDCG&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;all_results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ScoredMemory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;
            &lt;span class="py"&gt;.test_cases&lt;/span&gt;
            &lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.filter_map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.get_retrieved_results&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.ok&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;all_relevant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;
            &lt;span class="py"&gt;.test_cases&lt;/span&gt;
            &lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="py"&gt;.expected_results&lt;/span&gt;
                    &lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;er&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;er&lt;/span&gt;&lt;span class="py"&gt;.memory_id&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                    &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MeanAveragePrecision&lt;/span&gt;&lt;span class="nf"&gt;.calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;all_results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;all_relevant&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"map"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;MetricValue&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="s"&gt;"Mean Average Precision"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"score"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Mean Average Precision across all queries"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EvaluationResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;evaluator_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;dataset_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Utc&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="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"recall_evaluator"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MetricDefinition&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="n"&gt;MetricDefinition&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="s"&gt;"precision@k"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Precision at K"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"score"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;MetricDefinition&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="s"&gt;"recall@k"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Recall at K"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"score"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;MetricDefinition&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="s"&gt;"map"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Mean Average Precision"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"score"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;RecallEvaluator&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;fn&lt;/span&gt; &lt;span class="nf"&gt;evaluate_test_case&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;test_case&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Execute search&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;retrieved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;
            &lt;span class="py"&gt;.memory_manager&lt;/span&gt;
            &lt;span class="nf"&gt;.search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;test_case&lt;/span&gt;&lt;span class="py"&gt;.query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;Filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Build relevant memories set&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;test_case&lt;/span&gt;
            &lt;span class="py"&gt;.expected_results&lt;/span&gt;
            &lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;er&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;er&lt;/span&gt;&lt;span class="py"&gt;.memory_id&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Calculate Precision and Recall&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;precision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PrecisionAtK&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="nf"&gt;.calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;recall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RecallAtK&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="nf"&gt;.calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;relevant&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;precision&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recall&lt;/span&gt;&lt;span class="p"&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;fn&lt;/span&gt; &lt;span class="nf"&gt;get_retrieved_results&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;test_case&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ScoredMemory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.memory_manager&lt;/span&gt;
            &lt;span class="nf"&gt;.search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;test_case&lt;/span&gt;&lt;span class="py"&gt;.query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;Filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.config.max_results_per_query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;.await&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;h2&gt;
  
  
  4. Effectiveness Evaluation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Evaluation Dimensions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  4.1.1 Fact Extraction Accuracy
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;FactExtractionEvaluator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;llm_client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;LLMClient&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;FactExtractionEvaluator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;evaluate_extraction_accuracy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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="n"&gt;extracted_facts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ExtractedFact&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;ground_truth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ExtractedFact&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ExtractionAccuracy&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Calculate precision&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;precision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.calculate_precision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extracted_facts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ground_truth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Calculate recall&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;recall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.calculate_recall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extracted_facts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ground_truth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Calculate F1 score&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;precision&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;recall&lt;/span&gt; &lt;span class="o"&gt;&amp;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="mf"&gt;2.0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;precision&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;recall&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;precision&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;recall&lt;/span&gt;&lt;span class="p"&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="mf"&gt;0.0&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ExtractionAccuracy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;precision&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;extracted_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;extracted_facts&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;ground_truth_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ground_truth&lt;/span&gt;&lt;span class="nf"&gt;.len&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="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate_precision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;extracted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ExtractedFact&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;ground_truth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ExtractedFact&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;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;extracted&lt;/span&gt;&lt;span class="nf"&gt;.is_empty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&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="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;correct_count&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;extracted&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;is_correct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.is_fact_correct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ground_truth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&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;is_correct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;correct_count&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="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;correct_count&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;extracted&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&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;fn&lt;/span&gt; &lt;span class="nf"&gt;is_fact_correct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ExtractedFact&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ground_truth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ExtractedFact&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Use LLM to judge if the fact is correct&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"Compare the following fact with the ground truth facts:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
             Fact to evaluate: {}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
             Ground truth facts:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;{}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
             Is the fact correct and present in the ground truth? (yes/no)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="py"&gt;.content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;ground_truth&lt;/span&gt;
                &lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"- {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="py"&gt;.content&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="py"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;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="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.llm_client&lt;/span&gt;&lt;span class="nf"&gt;.complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.to_lowercase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"yes"&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="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ExtractionAccuracy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;precision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;extracted_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;ground_truth_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&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;h4&gt;
  
  
  4.1.2 Classification Correctness
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ClassificationEvaluator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;llm_client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;LLMClient&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;ClassificationEvaluator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;evaluate_classification_accuracy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;MemoryType&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ClassificationAccuracy&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;correct_count&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="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;total_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;for&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;expected_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;predicted_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.predict_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="py"&gt;.content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&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;predicted_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;expected_type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;correct_count&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="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;accuracy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;correct_count&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;total_count&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Calculate precision and recall for each category&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;per_class_metrics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.calculate_per_class_metrics&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ClassificationAccuracy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;overall_accuracy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;accuracy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;per_class_metrics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;total_count&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="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;predict_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MemoryType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"Classify the following memory content:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
             Content: {}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
             Classify as one of: Conversational, Procedural, Factual, Semantic, Episodic, Personal&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
             Classification:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;content&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.llm_client&lt;/span&gt;&lt;span class="nf"&gt;.complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;MemoryType&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&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;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate_per_class_metrics&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;MemoryType&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MemoryType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ClassMetrics&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MemoryType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ClassMetrics&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;for&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;expected_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;predicted_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.predict_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="py"&gt;.content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;// Update expected type metrics&lt;/span&gt;
            &lt;span class="n"&gt;metrics&lt;/span&gt;
                &lt;span class="nf"&gt;.entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;expected_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nf"&gt;.or_insert_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;ClassMetrics&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="py"&gt;.total&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;predicted_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;expected_type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="nf"&gt;.get_mut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;predicted_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.true_positives&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="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;metrics&lt;/span&gt;
                    &lt;span class="nf"&gt;.get_mut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;predicted_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="nf"&gt;.or_insert_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;ClassMetrics&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="py"&gt;.false_positives&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;metrics&lt;/span&gt;&lt;span class="nf"&gt;.get_mut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;expected_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.false_negatives&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="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Calculate precision and recall&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="nf"&gt;.iter_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.precision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.true_positives&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.false_positives&lt;/span&gt; &lt;span class="o"&gt;&amp;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;metric&lt;/span&gt;&lt;span class="py"&gt;.true_positives&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;
                    &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.true_positives&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.false_positives&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&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="mf"&gt;0.0&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;

            &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.recall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.true_positives&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.false_negatives&lt;/span&gt; &lt;span class="o"&gt;&amp;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;metric&lt;/span&gt;&lt;span class="py"&gt;.true_positives&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;
                    &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.true_positives&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.false_negatives&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&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="mf"&gt;0.0&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;

            &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.f1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.precision&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.recall&lt;/span&gt; &lt;span class="o"&gt;&amp;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="mf"&gt;2.0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.precision&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.recall&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.precision&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.recall&lt;/span&gt;&lt;span class="p"&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="mf"&gt;0.0&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metrics&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="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ClassMetrics&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;true_positives&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;false_positives&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;false_negatives&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;precision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;ClassMetrics&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;true_positives&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;false_positives&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;false_negatives&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;total&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;precision&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="n"&gt;recall&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="n"&gt;f1&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="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;h2&gt;
  
  
  5. Performance Evaluation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Benchmark Testing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;criterion&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;black_box&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;criterion_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;criterion_main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Criterion&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BenchmarkId&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;PerformanceBenchmark&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;memory_manager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MemoryManager&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;PerformanceBenchmark&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;benchmark_search_latency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Criterion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="nf"&gt;.benchmark_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"search_latency"&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;dataset_size&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.create_test_manager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dataset_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="nf"&gt;.bench_with_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nn"&gt;BenchmarkId&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset_size&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;dataset_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&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;b&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nf"&gt;black_box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                            &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                                &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                                &lt;span class="nf"&gt;.block_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="nf"&gt;.search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test query"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;Filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&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="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;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="nf"&gt;.finish&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;benchmark_insert_latency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Criterion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="nf"&gt;.benchmark_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"insert_latency"&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;content_length&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.create_test_manager&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;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="nf"&gt;.repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;content_length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="nf"&gt;.bench_with_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nn"&gt;BenchmarkId&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content_length&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;content_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&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;b&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nf"&gt;black_box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                            &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                                &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                                &lt;span class="nf"&gt;.block_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                                    &lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="nf"&gt;.create_memory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                                        &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                                        &lt;span class="nn"&gt;MemoryMetadata&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&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;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;span class="n"&gt;group&lt;/span&gt;&lt;span class="nf"&gt;.finish&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;benchmark_throughput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Criterion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.create_test_manager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="nf"&gt;.benchmark_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"throughput"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="nf"&gt;.bench_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"concurrent_searches"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

                &lt;span class="n"&gt;rt&lt;/span&gt;&lt;span class="nf"&gt;.block_on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;handles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                            &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&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;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="nf"&gt;.search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test query"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;Filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&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;.await&lt;/span&gt;
                            &lt;span class="p"&gt;})&lt;/span&gt;
                        &lt;span class="p"&gt;})&lt;/span&gt;
                        &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

                    &lt;span class="nn"&gt;futures&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;future&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;join_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&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;span class="n"&gt;group&lt;/span&gt;&lt;span class="nf"&gt;.finish&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="nd"&gt;criterion_group!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;benches&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="nn"&gt;Criterion&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.sample_size&lt;/span&gt;&lt;span class="p"&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;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PerformanceBenchmark&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;benchmark_search_latency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nn"&gt;PerformanceBenchmark&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;benchmark_insert_latency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nn"&gt;PerformanceBenchmark&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;benchmark_throughput&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;criterion_main!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;benches&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2 Load Testing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;load_testing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LoadTester&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;LoadTestRunner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;memory_manager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MemoryManager&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;LoadTestRunner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;run_load_test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;LoadTestConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LoadTestResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;tester&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;LoadTester&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.concurrent_users&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Add search tasks&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.search_requests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.memory_manager&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="nf"&gt;.add_task&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;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="nf"&gt;.search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test query"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;Filters&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&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;.await&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Add insert tasks&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.insert_requests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.memory_manager&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;tester&lt;/span&gt;&lt;span class="nf"&gt;.add_task&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;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;manager&lt;/span&gt;
                    &lt;span class="nf"&gt;.create_memory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test content"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;MemoryMetadata&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                    &lt;span class="k"&gt;.await&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Run test&lt;/span&gt;
        &lt;span class="k"&gt;let&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;tester&lt;/span&gt;&lt;span class="nf"&gt;.run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_secs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.duration_secs&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoadTestResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;total_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="py"&gt;.total_requests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;successful_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="py"&gt;.successful_requests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;failed_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="py"&gt;.failed_requests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;average_latency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="py"&gt;.average_latency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;p50_latency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="py"&gt;.p50_latency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;p95_latency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="py"&gt;.p95_latency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;p99_latency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="py"&gt;.p99_latency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;requests_per_second&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="py"&gt;.requests_per_second&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;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;LoadTestConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;concurrent_users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;search_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;insert_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;duration_secs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;LoadTestResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;total_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;successful_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;failed_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;average_latency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;p50_latency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;p95_latency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;p99_latency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;requests_per_second&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&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;h2&gt;
  
  
  6. Dataset Management
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 Dataset Generation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;DatasetGenerator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;llm_client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;LLMClient&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;DatasetGenerator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;generate_recall_dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RecallDatasetConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Dataset&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;test_cases&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.num_queries&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Generate query&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.generate_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.domain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;// Generate relevant memories&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;relevant_memories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.generate_relevant_memories&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="o"&gt;&amp;amp;&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;config&lt;/span&gt;&lt;span class="py"&gt;.num_relevant_per_query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;// Build expected results&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;expected_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;relevant_memories&lt;/span&gt;
                &lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|(&lt;/span&gt;&lt;span class="n"&gt;j&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;ExpectedResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;memory_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="n"&gt;relevance_score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&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;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;test_cases&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"query_{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;expected_results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TestCaseMetadata&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.domain&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="n"&gt;difficulty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.difficulty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="nn"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&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;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Dataset&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"recall_{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new_v4&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="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Recall Dataset - {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.domain&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Generated recall dataset for {} domain"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="py"&gt;.domain&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;test_cases&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DatasetMetadata&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;dataset_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;DatasetType&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Recall&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Utc&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="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;generate_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"Generate a natural language query for the {} domain. &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
             The query should be specific and realistic."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;domain&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.llm_client&lt;/span&gt;&lt;span class="nf"&gt;.complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="nf"&gt;.trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&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;fn&lt;/span&gt; &lt;span class="nf"&gt;generate_relevant_memories&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&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="o"&gt;&amp;amp;&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;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Memory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"Generate {} relevant memories for the following query:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
             Query: {}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
             Each memory should be a short, specific piece of information.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
             Format each memory on a new line."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;count&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.llm_client&lt;/span&gt;&lt;span class="nf"&gt;.complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Memory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
            &lt;span class="nf"&gt;.lines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.filter&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="nf"&gt;.trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.is_empty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="nf"&gt;.take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;content&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Uuid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new_v4&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="nf"&gt;.trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;vec!&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="mi"&gt;1536&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// placeholder&lt;/span&gt;
                &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;MemoryMetadata&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Utc&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="n"&gt;updated_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Utc&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="p"&gt;})&lt;/span&gt;
            &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memories&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="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;RecallDatasetConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;num_queries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;num_relevant_per_query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;difficulty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Difficulty&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;h3&gt;
  
  
  6.2 Dataset Loading
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;DatasetLoader&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;DatasetLoader&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;load_from_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Dataset&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&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;let&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;BufReader&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&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="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&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="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;save_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&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;path&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;let&lt;/span&gt; &lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;BufWriter&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;to_writer_pretty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dataset&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="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;load_from_directory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&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;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Dataset&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;datasets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&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;entry&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;read_dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dir&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;let&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="nf"&gt;.path&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;path&lt;/span&gt;&lt;span class="nf"&gt;.extension&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.and_then&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.to_str&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;load_from_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="nf"&gt;.to_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&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;datasets&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&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="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;datasets&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;h2&gt;
  
  
  7. Report Generation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Markdown Report
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;MarkdownReportGenerator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;MarkdownReportGenerator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;generate_report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;EvaluationResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Title&lt;/span&gt;
        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"# {} Evaluation Report&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.evaluator_name&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="c1"&gt;// Metadata&lt;/span&gt;
        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"## Metadata&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"- **Dataset ID**: {}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.dataset_id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"- **Timestamp**: {}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.timestamp&lt;/span&gt;&lt;span class="nf"&gt;.format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%Y-%m-%d %H:%M:%S UTC"&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Metrics&lt;/span&gt;
        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"## Metrics&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"| Metric | Value | Unit | Description |&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"|--------|-------|------|-------------|&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;for&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;metric&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.metrics&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"| {} | {:.4} | {} | {} |&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.unit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="py"&gt;.description&lt;/span&gt;
            &lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Details&lt;/span&gt;
        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"## Details&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"- **Test Cases Passed**: {}/{}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.details.test_cases_passed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.details.test_cases_total&lt;/span&gt;
        &lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.details.errors&lt;/span&gt;&lt;span class="nf"&gt;.is_empty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;### Errors&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&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;error&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.details.errors&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"- **{}**: {}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="py"&gt;.test_case_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="py"&gt;.message&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.details.warnings&lt;/span&gt;&lt;span class="nf"&gt;.is_empty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;### Warnings&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&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;warning&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="py"&gt;.details.warnings&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"- **{}**: {}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="py"&gt;.test_case_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="py"&gt;.message&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="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;report&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;h3&gt;
  
  
  7.2 JSON Report
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;JsonReportGenerator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;JsonReportGenerator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;generate_report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;EvaluationResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;to_string_pretty&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="nf"&gt;.map_err&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;MemoryError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Serialization&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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;h2&gt;
  
  
  8. Usage Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 Running Evaluation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Initialize components&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"config.toml"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_memory_manager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create dataset&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_test_dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create evaluator&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;evaluator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;RecallEvaluator&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;RecallEvaluatorConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;k_values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&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="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;similarity_thresholds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&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="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;max_results_per_query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Run evaluation&lt;/span&gt;
    &lt;span class="k"&gt;let&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;evaluator&lt;/span&gt;&lt;span class="nf"&gt;.evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Generate report&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MarkdownReportGenerator&lt;/span&gt;&lt;span class="nf"&gt;.generate_report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&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="c1"&gt;// Save report&lt;/span&gt;
    &lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"evaluation_report.md"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;report&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="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Evaluation completed successfully!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Report saved to evaluation_report.md"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&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;h3&gt;
  
  
  8.2 Continuous Integration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/evaluation.yml&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Memory Evaluation&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;evaluate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Rust&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions-rs/toolchain@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;
          &lt;span class="na"&gt;toolchain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stable&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run evaluation&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;cargo run --bin evaluation -- \&lt;/span&gt;
            &lt;span class="s"&gt;--dataset ./datasets/test.json \&lt;/span&gt;
            &lt;span class="s"&gt;--output ./reports/evaluation.md&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload report&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;evaluation-report&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./reports/evaluation.md&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  9. Summary
&lt;/h2&gt;

&lt;p&gt;Cortex Memory's evaluation framework provides the following capabilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Comprehensive metrics&lt;/strong&gt;: Covers recall, effectiveness, and performance dimensions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible dataset management&lt;/strong&gt;: Supports multiple data sources and generation methods&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple evaluators&lt;/strong&gt;: Pluggable evaluator architecture&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rich report formats&lt;/strong&gt;: Supports Markdown, JSON, and other formats&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD integration&lt;/strong&gt;: Easy to integrate into continuous integration workflows&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This evaluation framework provides scientific, quantitative metrics for memory system optimization, ensuring continuous improvement of system quality and performance.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nlp.stanford.edu/IR-book/html/htmledition/evaluation-of-ranked-retrieval-results-1.html" rel="noopener noreferrer"&gt;Information Retrieval Evaluation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://trec.nist.gov/data/guidelines/" rel="noopener noreferrer"&gt;TREC Guidelines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/performance-testing/9781449387758/" rel="noopener noreferrer"&gt;Performance Testing Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>openai</category>
      <category>rust</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
