Univoco Hardens Coding Agent Failures
- •Univoco hardened a private-documentation coding agent after search, retrieval, and edit failures appeared in production
- •Loop controls stopped repeated lookups, including one turn with 12 steps and 170k input tokens
- •`lookup_docs` runs in milliseconds without generation, while `rag_lookup` takes ten to thirty seconds and can invent
Univoco engineer Joe Buckle published a July 31 account of how his team hardened a retrieval-augmented coding agent that writes code for a proprietary document layout engine, where public internet memorisation could not help because the engine has effectively no public documentation. The agent depended on a private documentation index and search tools, making failures visible when retrieval, tool routing, or edit checks broke down.
The first failure came from literal search. The agent searched file contents for `json`, missed an existing `sampleData.json` file because the term appeared only in the filename, and offered to create a file that already existed. Univoco changed project search so filenames are part of the searchable surface. A second search failure appeared when the agent deleted only one matching line while removing a feature, even though the related object was declared and configured across nearby lines. `find_in_files` was changed to return grep-style context plus an automatic variable footprint, including lines such as `var box = new Block()` and property lines tied to the same declared variable.
Univoco split tools into a generic base layer and customer-specific client layer. Base tools such as `list_files`, `read_file`, `find_in_files`, `write_file`, `edit_file`, `apply_edit`, and `delete_lines` are shared across customers. Client tools such as `lookup_docs`, `resolve_topic`, `find_construct`, `check_symbols`, and `dry_run` depend on the customer’s documentation and object model. A client tool can shadow a base tool of the same name; the client `find_in_files` expands concept words such as “block” or “the box” into the engine’s real symbols when literal search fails.
The team separated two knowledge tools because they had different reliability profiles. `lookup_docs` performs full-text documentation search with no embeddings and no generation, returns chunks that literally contain a term, runs in milliseconds, and cannot invent APIs. `rag_lookup` uses semantic retrieval plus model-written answers, takes ten to thirty seconds, and can invent. The agent was instructed that naming a known symbol is a fact check for `lookup_docs`, while broader “how do I build” questions can use `rag_lookup`.
The largest loop failure occurred when the agent ran the same knowledge lookup twelve times in one turn with identical arguments, even after results said it had already asked. Another table-related turn used 12 steps and 170k input tokens, with three of five knowledge lookups re-confirming the same three API names already present in context. Univoco added five loop controls: identical-call blocking after `_MAX_IDENTICAL_CALLS = 4`, per-turn lookup limits including `_MAX_LOOKUPS_PER_TURN = 12` and `_MAX_LIVE_LOOKUPS = 2`, deterministic cross-turn query matching, leader/follower collapse for concurrent duplicates, and exemptions when prompt fragments already declare provided symbols.
The cross-turn duplicate detector avoids embeddings. It lowercases text, removes stopwords, applies light stemming with double-consonant collapse, sorts tokens, and then checks exact keys or `difflib` close matches. The similarity threshold is `0.8`; a live pair differing only by a domain word scored 0.833, while `create table` and `create box` scored about 0.73. Buckle wrote that the measured gap made the threshold trustworthy.
The budget system also changed after it cut off a model while it was correctly verifying eleven symbols. Univoco moved from charging every call to charging by tool, so cached results and cheap tools are free. The configuration notes that `_MAX_LOOKUPS_PER_TURN` caps live lookups across wordings, while cached serves and cheap tools are free through `projects.budget_tools`, defaulting to `rag_lookup`. The article says a millisecond `lookup_docs` fact-check per symbol is diligence, not a cost to ration.
Query inflation addressed recall failures caused by one user phrasing. Before lookups run, a forced `search_queries` tool reformulates a question into 2-3 different angles for how-to tasks, including a focused how-to query, a broad keyword query using core nouns or concepts, and, when allowed, a concrete-example query. Only trivial factual lookups should produce one query. The prompt explicitly says never to echo the question verbatim, because shuffled wording recreates the same reworded-not-rethought problem.