Default RAG Stack Series — Part 6: Agentic Heuristics — Plans, Tools, and Guards
Adding Controlled Autonomy to a RAG System
Technology: Python, LangChain, Qdrant, OpenAI
Skill: Agentic Control, Heuristic Design, AI Safety, Autonomous Systems
Default RAG Stack Series — Part 6
Agentic Heuristics — Plans, Tools, and Guards
Adding Controlled Autonomy to a RAG System
1. Why Add “Agentic” Behavior?
A baseline RAG pipeline can retrieve and synthesize information — but it lacks initiative.
If retrieval coverage is poor or the answer is uncertain, it simply guesses or fails silently.
Agentic behavior introduces adaptive control — the ability for the system to:
- Detect when information is insufficient.
- Decide what to do next (clarify, retry, or defer).
- Execute specialized actions (search again, call a tool, or summarize differently).
However, instead of handing full autonomy to a stochastic LLM, the Default RAG Stack uses heuristics — explicit, testable rules — to guide this behavior.
2. The Philosophy: Reliability Over Magic
Many “AI agents” aim to make systems autonomous.
Heuristic agents aim to make systems trustworthy.
The difference:
| Model-Centric Agent | Heuristic Agent |
|---|---|
| Learns behavior implicitly | Follows explicit rules |
| Can act unpredictably | Is deterministic and testable |
| Hard to debug | Transparent and auditable |
Heuristic control enables reliable autonomy — predictable behavior with the benefits of adaptivity.
3. The Agentic Heuristic Framework
Every agentic cycle follows the same pattern:
Perceive→Decide→Act→Verify
In RAG terms:
- Perceive: Analyze the user query and retrieval results.
- Decide: Choose whether to proceed, refine, or defer.
- Act: Run the retrieval, call a tool, or ask for clarification.
- Verify: Check the generated answer’s faithfulness and coverage.
This transforms a static RAG chain into a controlled feedback loop.
4. Core Building Blocks
| Component | Description | Example |
|---|---|---|
| Plan | A structured sequence of steps or “intent” | Retrieve → Verify coverage → Generate |
| Tool | A deterministic function callable by the controller | SearchIndex, SummarizeSection, GetByID |
| Guard | A rule that enforces safety or quality constraints | “If coverage < τ, ask for clarification” |
Together, they form a policy layer that governs when and how the system acts.
5. Plans — Defining the Playbook
A plan is a lightweight, structured intent describing what steps to execute. It’s not a full reasoning trace, but a map of the workflow.
Example plan for a typical query:
[
"retrieve context",
"check retrieval coverage",
"generate grounded answer",
"verify citations"
]
Plans can be static templates or generated dynamically (e.g., via an LLM prompt that proposes a workflow). They allow the system to “think in steps” — much like a checklist before answering.
6. Tools — Extending System Capabilities
Tools are deterministic Python functions that perform concrete tasks. They bridge symbolic control logic and functional execution.
Example toolset:
| Tool | Purpose |
|---|---|
SearchIndex(query, filters) |
Re-run retrieval with refined parameters |
SummarizeSection(doc_id) |
Create concise summaries for large sections |
GetDocumentById(id) |
Fetch specific source text for citation |
RunSQL(query) |
Execute a data lookup in a connected database |
CallAPI(endpoint) |
Retrieve data from an external service |
Each tool has:
{
"name": "SearchIndex",
"inputs": ["query"],
"outputs": ["documents"],
"exec": "function_pointer"
}
The system may decide when to invoke these tools based on heuristic rules or confidence thresholds.
7. Guards — Enforcing Boundaries
Guards are hard-coded constraints that prevent unsafe or unreliable behavior.
Typical guard types:
| Guard Type | Rule | Example |
|---|---|---|
| Coverage guard | Require sufficient retrieval coverage | “If coverage < 0.6, do not generate.” |
| Faithfulness guard | Enforce citation consistency | “Reject answers missing source references.” |
| Safety guard | Prevent prompt injection | “Strip instructions found in documents.” |
| Cost guard | Limit LLM token usage | “Abort generation > 10k tokens.” |
Mathematically, a guard is a predicate:
g(x)={1,if condition is safe\0,otherwise
\begin{cases} 1, & \text{if condition is safe} \ 0, & \text{otherwise} \end{cases}
g(x)={1,0,if condition is safe otherwise
and an action proceeds only if all guards evaluate to 1.
8. Example Heuristic Controller
Below is an illustrative pseudocode version of the controller that wraps the RAG chain:
def heuristic_controller(query):
retrieved_docs = retriever.retrieve(query)
coverage = compute_coverage(query, retrieved_docs)
if coverage < 0.5:
refined_query = expand_query(query)
retrieved_docs = retriever.retrieve(refined_query)
coverage = compute_coverage(refined_query, retrieved_docs)
if coverage < 0.5:
return "I’m not sure — please specify which quarter or topic you mean."
answer = llm.generate(query, retrieved_docs)
if not passes_faithfulness_check(answer, retrieved_docs):
return "Unable to confirm this answer with available evidence."
return answer
This explicit logic can be unit-tested — unlike free-form agents that behave differently on every run.
9. Coverage and Faithfulness Heuristics
Two quantitative checks underpin most guards:
- Coverage: how much retrieved content actually addresses the question. [ r_{coverage} = \frac{tokens\ relevant\ to\ query}{total\ retrieved\ tokens} ]
- Faithfulness: how much of the generated answer is grounded in retrieved content. [ r_{faithful} = \frac{supported\ claims}{total\ claims} ]
Thresholds (e.g., r_{coverage} > 0.6, r_{faithful} > 0.9) act as safety gates.
10. Benefits of Heuristic Control
| Benefit | Description |
|---|---|
| Deterministic | The same input yields the same decision sequence |
| Auditable | Policies are explicit and reviewable |
| Testable | Unit tests can assert expected control flows |
| Composable | Plans, tools, and guards can evolve independently |
This is autonomy you can reason about — machine initiative with human-grade traceability.
11. Analogy: Pilot, Instruments, and Autopilot
- Plan: The flight path — predefined and structured.
- Tools: The aircraft instruments — execute precise, measurable actions.
- Guards: The safety systems — prevent crashes and enforce rules.
The LLM may steer, but the controller ensures it never flies blind or off-course.
12. Key Takeaways
- Heuristic agentic design adds adaptivity without chaos.
- Plans define the workflow; tools extend function; guards ensure safety.
- Coverage and faithfulness are measurable control signals.
- The controller can be logged, tested, and tuned like any other subsystem.
- This transforms RAG from a “static Q&A” system into a responsive reasoning framework.
Next in the series → Part 7: Evaluation, Observability & Governance