How Rewire built a voice agent that rewrites itself after every wrong answer
This article was originally published on the Actian blog. The build was first submitted to the Self-Evolving Agents Hackathon. This post breaks down Rewire, a voice agent system that repairs its own workflow after a wr
This article was originally published on the Actian blog. The build was first submitted to the Self-Evolving Agents Hackathon.
This post breaks down Rewire, a voice agent system that repairs its own workflow after a wrong answer. It traces the failure to the node responsible, generates competing fixes, replays past calls to reject any fix that breaks something, and stores the survivor in Actian VectorAI DB. You'll see the memory commit code, the failure signature that makes fixes reusable, and three patterns to apply in your own agents.
The headline result came from two unrelated agents. An auto-servicing agent fabricated a brake price, and Rewire fixed it. Later, a healthcare agent fabricated a $40 insurance copay against a verified $47, retrieved that brake-pricing fix, and corrected the copay on its first try. Builder Aayush Gupta summed up the approach. "We wrote the fitness function. It wrote the rules."
The results
| Metric | Value |
|---|---|
| Candidate fixes per generation | 3, each from a different mutation operator |
| Candidates generated across the run | 33 |
| Candidates rejected by the validator | 27 |
| Cross-domain transfer | Brake-pricing fix corrected a $40 copay to the verified $47 |
Why prompt engineering falls short
Patching a prompt by hand fixes one instance. The same mistake can show up in another workflow, and you write the patch again there.
Prompts also change behavior probabilistically. Telling an agent to look up an approved price doesn't guarantee it calls the lookup tool. RAG improves what gets retrieved, and Rewire targets the instruction or routing that failed to trigger retrieval at all. In Gupta's words, "Nobody touches a prompt."
How the loop is wired
- Dograh orchestrates and versions the conversation flow.
- Pioneer serves inference through an OpenAI-compatible endpoint running gpt-5.4-mini. Each call returns the node, instructions, tools, tool calls, and transitions.
-
Senso returns the verified answer with a citation.
SensoOraclecompares the agent's response against it and returns a verdict with a correctness score, groundedness, the ground-truth value, the failure type, diagnostic reasoning, and an escalation result. - The validator traces the root node, generates patches, replays them against history, and updates the live graph.
- VectorAI DB stores domain-free failure signatures with their patches.
In the brake-pricing failure, the agent had the knowledge-base tool available and never called it. Senso supplied the verified price.
1. Trace the failure to its root node
Rewire follows Dograh's node_transition events and execution history to find the node that caused the failure. That can differ from the node that spoke the wrong answer.
2. Generate competing fixes
The failure signature picks from four bounded mutation operators.
| Operator | What it changes |
|---|---|
append_constraint |
Adds a constraint to the node's existing instruction |
add_tool_requirement |
Requires a specific tool call under a defined condition |
rewrite_instruction |
Replaces the node's instructions |
change_transition |
Changes graph routing |
Each generation produces three candidates from structurally different operators. For the brake price, the winner was add_tool_requirement, which made pricing_lookup call the knowledge base before quoting any specific price.
3. Kill fixes by replay
A Guild-hosted validator applies each candidate to a local copy of the workflow and replays historical calls. A candidate survives only if it fixes the failure without breaking behavior that was already correct. The survivor with the highest validation confidence goes live. Across the run, 27 of 33 candidates didn't survive.
4. Commit the fix to VectorAI DB
The vector comes from the failure signature, which records the node's role, the failure type, whether a retrieval tool was available, whether it was invoked, and whether the agent asserted a specific value. The caller's words and domain terms stay out.
def to_embedding_text(self) -> str:
"""The ONLY text that may be embedded into `signature_vector`.
Deliberately reads as structured English rather than a token soup:
we want semantically *near* signatures (same failure type, same role,
differing only in whether a tool existed) to land near each other in
vector space, which a bag of flags would not achieve.
Note what is absent: the utterance, the ground truth, the vertical,
the node id, the product. If you are tempted to add any of them here
to improve retrieval precision, that is the transfer beat dying.
"""
return (
f"A {self.node_role.value} node produced a {self.failure_type.value} failure. "
f"A retrieval tool was {'available' if self.tool_available else 'not available'} "
f"and was {'invoked' if self.tool_invoked else 'not invoked'}. "
f"The agent {'asserted a specific factual value' if self.asserted_specific_value else 'did not assert a specific value'}."
)
That method, from the project's repo, builds the only text that gets embedded. The store() method commits a validated patch.
def store(self, patch: WorkflowPatch) -> str:
"""Embed the patch's failure signature, upsert with its flat payload.
Returns the Actian point id (a uuid5 of `patch.patch_id`, so this is a
true upsert — storing the same patch twice after validation flips it
from candidate to promoted in place rather than duplicating it).
"""
self._require_ready()
vector = embed(patch.signature.to_embedding_text())
pid = point_id_for(patch.patch_id)
self.client.points.upsert(
self.collection,
[PointStruct(id=pid, vector=vector, payload=patch.to_actian_payload())],
)
return pid
store() embeds the signature text into a 384-dimensional vector and derives a deterministic point ID from the patch ID with uuid5. Because the ID is stable, storing the same patch again after validation updates the existing point from candidate to promoted, so no duplicate appears.
Why the healthcare agent matched
The copay failure and the brake failure share a shape. In both, the agent asserted a specific value while a verification tool sat unused. With domain words left out of the embedding, that shape is all VectorAI DB compares. Gupta said the healthcare agent "matched purely on the shape of the failure, and fixed a fabricated insurance copay first try."
The retrieved fix still went through validation before touching the healthcare graph.
Three patterns to reuse
| Pattern | What Rewire did | What you implement |
|---|---|---|
| Index by shape | Encoded failure signatures from structural properties and stored them in VectorAI DB without domain content | Define a normalized failure schema describing how the agent failed, then embed it |
| Eliminate by replay | Tested generated and retrieved fixes against the triggering failure and historical calls, promoting only fixes with no regressions | Apply each candidate to the current workflow, replay representative cases, and promote only after a regression gate |
| Let the agent write the rules | Let the agent propose graph updates within bounded mutation operators, then validated the result | Constrain the operators, let the agent propose rules, and let execution-based validation pick survivors |
Embed only the failure representation you want reused. Full conversations bring in domain vocabulary that narrows matches to one vertical.
Wrapping up
Rewire records how a failure happened, keeps only fixes that pass replay, and stores them where any agent can find them by shape. That's how a fix written for brake prices ended up correcting an insurance copay.
What's next
- Run VectorAI DB locally with
docker pull actian/vectorai:latestand try VectorAI DB Community Edition. - Read the full system in the Rewire repository.
- Compare a related pattern in how Regenesis built MedShift's self-healing loop with VectorAI DB.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.