Skip to content
All writing

AI engineering2026Work in progress8 min

Teaching a debugging agent where to look first

I am building an AI agent that debugs parasitic-extraction runs inside a locked-down VM, with no vector database and no embedding model. It follows a 14-phase roadmap, one gated phase at a time. The newest layer tells it which playbook fits a debugging task and which files to open first.

Role
Solutions Engineer, Cadence Design Systems
My part
Roadmap, phase gates and design reviews; a coding agent implements each phase
Timeline
2026, ongoing
Stack
Python 3.8, SQLite, scikit-learn, difflib, JSON
Scope
Retrieval, provenance, evaluation and intent routing
  • AI agents
  • Information retrieval
  • Hybrid search
  • Evaluation
  • Python
  • SQLite
Problem
Engineers debugging parasitic-extraction runs need answers grounded in manuals, bug records and the run itself, found inside a locked-down VM with no vector database and no embedding model.
Approach
A 14-phase roadmap, one gated phase at a time: measure the environment, define provenance, build hybrid lexical search, benchmark it, and only then give the agent more autonomy.
Where it stands
Work in progress. The citations phase closed with 390/390 regression tests passing. The newest layer matches debugging tasks to playbooks and tells the agent which files to open first.

The first search worked up to a few hundred entries

I work as a Solutions Engineer on parasitic extraction: debugging runs, automation and data inspection around a PEX tool. The agent I am building debugs extraction runs and answers product questions, grounded in what the team already knows.

That knowledge lives in curated units called pills (symptom, root cause, fix, evidence), plus extraction options, error entries, bug records and debug learnings. The original search read a JSON index, filtered it and used fuzzy matching to survive typos. It worked up to a few hundred pills.

I wanted a tool that could hold everything without saturating the context window, and that always knew what was available and what to use.

The VM sets the architecture

Everything runs inside a locked-down virtual machine where nothing can be installed.

Runtime
Python 3.8, no package installs
Available
sqlite3, json, csv, difflib, multiprocessing, NumPy, SciPy, scikit-learn, pandas, plotting libraries
Not available
Vector stores (FAISS, ChromaDB), embedding models and PyTorch, LangChain and LlamaIndex, Whoosh and Elasticsearch, NLTK and spaCy, rapidfuzz
Knowledge at the start
180 pills, 132 extraction options, 45 error entries, 48 bug records

Phases 0–14

Fourteen phases, one gate at a time

I planned the roadmap up front with a deep-research pass. Each phase ends at a stop gate with explicit acceptance criteria: a coding agent implements it, I read the report and decide whether we continue.

  1. Measure the environment

    Phases 0–1.5

    A capability probe writes what the VM really offers (modules, SQLite full-text search, PDF and shell tools) to a file the agent reads instead of guessing. Every path sits behind one variable, and the agent must never print a physical one.

  2. Register the tools

    Phase 2

    Each in-house script gets an entry: when to use it, when not to, inputs, output and risk level.

  3. Define provenance

    Phase 3

    Evidence types, shared metadata and applicability rules, before any work on search quality.

  4. Build hybrid lexical search

    Phases 4–6

    Exact identifiers, metadata filters and fuzzy matching, then BM25 or TF-IDF, then rank fusion.

  5. Benchmark before continuing

    Phase 7

    A golden set scored with Recall@k and MRR, with nDCG to follow.

  6. Add structure and citations

    Phases 8–10.5

    Relation expansion, structure-aware manuals and a source id on every result, plus documentation checks, 12 behavioural benchmark prompts and a compact checkpoint so a fresh chat can recover the project state.

  7. Make it agentic, then earn the rest

    Phases 11–14

    Retrieval that abstains when its evidence is insufficient, a slimmer main prompt, embeddings only if the benchmark demands them, and continuous evaluation.

Provenance came before search quality

The tempting order is to improve search first. I defined evidence first. A manual states expected behaviour, a bug record describes a failure in specific builds, a run shows what actually happened, and a model inference is only an inference. The agent has to know which one it is holding.

Every entry carries its source type, process, mode, affected builds, fixed-in build, validation status and content hash. That metadata also decides when two claims really conflict: "release A requires option X" and "release B no longer requires it" are not a contradiction. They apply to different builds.

Six channels, fused by rank

Exact codes, typos and plain-language symptoms need different matchers, so the search runs several and fuses their rankings. JSON stays the source of truth; the SQLite index is rebuilt from it.

  1. 01

    Query

    What the engineer typed

    • Exact codes and option names
    • Typos and partial names
    • Natural-language symptoms
  2. 02

    Channels

    Each one ranks candidates on its own

    • Exact identifiers
    • Metadata filters: process, mode, build
    • BM25 over SQLite full-text search
    • TF-IDF on words (1–2-grams)
    • TF-IDF on characters (3–5-grams)
    • Fuzzy identifiers (difflib)
  3. 03

    Fusion

    Reciprocal rank fusion

    • Ranks, never raw scores
    • Exact identifiers first
    • Penalty for the wrong process, build or mode
  4. 04

    Results

    Ranked and explained

    • Score components for every rank
    • A source id on every hit

Fusion uses ranks because BM25, TF-IDF and fuzzy-match scores do not share a scale. Each result keeps its score components, so the search itself can be debugged.

A perfect score is a baseline, not a proof

Before relations, manuals or agentic behaviour, the search had to be measurable. The golden set mixes exact codes, typos, options, partial names, natural-language symptoms, build-specific and multi-hop questions, plus questions the knowledge base cannot answer, because a good search must sometimes come back empty.

The first run scored 1.000 on every metric. I did not read that as proof: 28 queries can show that nothing obvious is broken, not that nothing is. I expanded the set and kept the score as a baseline, the same way I treat a backtest that looks too good.

Queries in the first golden set
28
26 with an expected answer
Recall@1, @5, @10 and MRR
1.000
First golden set, before expansion
Regression tests passing
390/390
Citations phase gate
Physical paths leaked
0
Same gate

Internal benchmark and regression suites. Golden-set figures are from the set's first version, since expanded.

Manuals split by structure, claims tied to sources

Relations came next, as a GraphRAG-lite with no graph database: errors link to pills, pills to bug records, bug records to options. One hop by default, two for complex troubleshooting, never everything.

Official manuals only arrived after that, starting with a single one. The original is kept, hashed and tagged with its release, then split along its own structure (chapter, section, subsection, option, procedure, table) with page ranges, instead of fixed 500-word chunks.

Then citations. Every result carries a source id, so a conclusion can keep apart what the manual says should happen, what a bug record says happens in a given build and what the current run shows, before concluding that the run matches a known bug.

Newest layer

Knowing the answer is not knowing where to look

By August 2026 the agent retrieved knowledge well. Pointed at a run directory, though, it did not know which files to open first: it had no picture of the flows that produced them.

I added two layers. User-intent search returns a procedure for the requested kind of task alongside the knowledge results. Version one matched requests lexically against synonym groups, with stopwords and a threshold, over 11 procedures stored as procedure pills.

Flow file knowledge is a search over each flow's files and documentation. When the agent finds something, it knows which flow document it belongs to, which artifacts the flow produces (setup script, run summary, extraction outputs, SPEF or DSPF netlists) and what each one helps diagnose.

A design review turned rails into playbooks

Version one drifted towards rails: an intent lookup on every task, a fixed checklist, the procedure repeated on every search. I reviewed it against Anthropic's Agent Skills (progressive disclosure), Anthropic's "Building effective agents" (workflows versus agents, routing), Agent Workflow Memory and ReAct, then applied the changes through one consolidated prompt.

The main change separates two memories. Declarative knowledge answers "what do we know about this error?". Procedural knowledge answers "given this run, what do I look at first, where, and in what order?". A capability is what can be done, a procedure how to do it, a tool what executes it, and file knowledge where the evidence lives.

A procedure is now a playbook: purpose, first checks, expected artifacts, first actions, stop conditions and a fallback. Its decision points branch on evidence: a failed extraction leads to the errors, a completed one to output validation, a netlist anomaly to the netlist procedure.

Route once, by request type

Request
  1. A fact from internal knowledge

    Knowledge search

    Ranked, cited entries ending in short next hints

  2. What the official documentation says

    Manual search

    Manual fragments with release, section and pages

  3. What this run actually shows

    Run-evidence search

    Evidence from the current run

  4. An action, workflow, debug or investigation

    Procedure lookup, then act

    One primary playbook, plus optional related ones

    • STRONG
    • POSSIBLE
    • NO_MATCHgeneral technical work

    A named strength, no invented percentages. Never several procedures with equal authority.

  5. Something unfamiliar

    Inspect first

    General technical work

Re-route only when

  • the sub-problem clearly changes
  • the procedure no longer applies
  • another domain appears
  • the agent is stuck

Six changes that loosened the rails

DecisionRailsPlaybooks
When to routeAn intent lookup on every taskOnce, by request type; re-route only if the problem changes or the agent is stuck
What comes backTop three procedures, with equal authorityOne primary procedure with a match strength, plus optional related ones
What a procedure isA fixed checklistA playbook that branches on evidence
How rules are written"NEVER use find""Prefer known flow locations; use targeted discovery; avoid broad recursive scans"
Knowledge searchesRe-inject the full procedureEnd with small next hints: manual, run evidence, related procedure
Where a workflow livesRestated in the intent file, the procedure entries and the promptOnce: intent metadata points to the procedure object

Re-injecting a procedure wastes tokens and can send the model back to step one. NEVER survives only for dangerous invariants.

Route once, guide progressively, inspect real evidence, retrieve knowledge when the evidence demands it — and let the agent adapt.
The design principle behind the routing layer

The next benchmark scores what the agent does next

Retrieval metrics cannot judge this layer, so it has its own: top-1 intent accuracy, top-3 recall, precision when no intent applies, and wrong-procedure activations. The last one matters most. Activating the wrong procedure is worse than finding none.

A workflow benchmark scores what the agent does next: filesystem calls, broad recursive searches, knowledge-search calls, repeated searches, step count and whether the first action was useful. The main prompt keeps only behaviour, and its token count is tracked before and after.

This layer is work in progress, and those numbers will judge it. The goal is not to tell the agent exactly what to do, but to give it a road map so it stops driving across the fields.

Six rules, each backed by a phase

  1. 01

    Measure the environment before designing for it

    Assumptions about what is installed become silent failures. A probe writes them down once.

    Phases 0–1

  2. 02

    Define evidence before improving search

    The agent must tell a manual fact from a bug record, a run observation or its own inference.

    Phases 3 and 10

  3. 03

    Benchmark before the next feature

    A perfect score on a small set is a reason to write harder queries, not to stop.

    Phase 7: 28 queries, since expanded

  4. 04

    Keep what you know apart from how you work

    Knowledge and procedures are different objects, reached by different routes, each defined once.

    Intent routing, August 2026

  5. 05

    Earn every layer of complexity

    No LangChain, no vector store, no full GraphRAG, and no model reading thousands of entries that Python can filter. Embeddings join only if failing queries prove a vocabulary gap.

    Phase 13 is conditional

  6. 06

    Guide the agent; do not script it

    Playbooks with a fallback, preferences over bans, NEVER only for dangerous invariants. A wrong procedure costs more than none.

    Wrong-procedure activations are tracked

Get in touch

Working on something similar? I am happy to compare notes.