Skip to main content
C carlos.enredando.me CTO · Advisor · Builder
Mastering Agentic AI: Reasoning Techniques
Chess — photo by Hassan Pasha on Unsplash.

Mastering Agentic AI: Reasoning Techniques

·1516 words·8 mins
Carlos Prados
Author
Carlos Prados
Telecommunications Engineer, Entrepreneur, CTO & CIO, Team Leader & Manager, IoT-M2M-Big Data Consultant, Pre-sales Engineer, Product-Service Manager & Strategist.

In my previous post, we looked at Resource-Aware Optimization — teaching agents to spend tokens, latency, and money deliberately instead of burning the biggest model on every request. That pattern is about how much to think. This one is about how to think.

Most LLM failures on hard problems aren’t knowledge failures. The model knows the facts. It just blurts out the answer in one shot, skips the intermediate steps, and gets the logic wrong. Ask it to compute compound interest or untangle a multi-hop question and it will confidently hand you a plausible-looking mistake.

That’s where the Reasoning Techniques pattern comes in. It’s the difference between an agent that responds and an agent that works through a problem — and it’s the substrate that every advanced agent behavior is built on top of.

Pattern #17: Reasoning Techniques
#

The Problem
#

A single forward pass through an LLM is a guess. A very good guess, often — but for anything that requires multiple logical steps, the model that answers immediately is the model that’s most likely to be wrong.

Three failure modes show up constantly in production:

  1. No intermediate steps. The model jumps straight to a conclusion. There’s no scratchpad, so there’s nowhere for the logic to live, and nowhere for you to inspect where it went wrong.
  2. No self-check. The first draft ships. The model never asks itself whether the output actually satisfied the original requirements.
  3. No iteration. Hard research questions need a loop — search, evaluate, decide whether you have enough, search again. A straight-line pipeline can’t do that.

Reasoning Techniques is the umbrella for the structural moves that fix all three: make the model show its work, make it critique its own work, and give it a graph that can loop until the work is good enough.

The Solution
#

There’s no single “reasoning” API. It’s a family of techniques that range from a prompt tweak to a full stateful graph. The chapter covers the spectrum, so let’s walk it from cheapest to most structured.

1. Chain-of-Thought (CoT) — The cheapest, highest-leverage move you can make. You don’t change the architecture; you change the prompt to force an explicit, ordered thought process before the answer:

COT_REASONING_PROMPT = """
You are an Information Retrieval Agent. Your goal is to answer the user's question comprehensively and accurately by thinking step-by-step.

Here's the process you must follow:

1.  **Analyze the Query:** Understand the core subject and specific requirements. Identify key entities and keywords.
2.  **Formulate Search Queries:** Generate a list of precise search queries you would use.
3.  **Simulate Information Retrieval:** Mentally consider what kind of information you expect to find. Identify potential ambiguities.
4.  **Synthesize Information:** Combine your understanding into a coherent and complete answer.
5.  **Review and Refine:** Critically evaluate your answer for accuracy, clarity, and conciseness.

User Query: "{query}"

Please provide your internal 'Thought Process' followed by your 'Final Answer'.
"""

The trick is the last line: separate the Thought Process from the Final Answer. The model spends tokens reasoning, and those tokens condition the answer that follows. It’s not magic — it’s giving the model room to compute before it commits.

2. Self-Correction — One pass is a draft. The reasoning move is to add a second pass whose only job is to be hostile to the first. You feed the original requirements and the generated content back in, and ask for a critique plus a rewrite:

SELF_CORRECTION_PROMPT = """
You are a highly critical and detail-oriented Self-Correction Agent. Your task is to review a previously generated piece of content against its original requirements and identify areas for improvement.

Process:
1.  **Understand Original Requirements:** What was the original intent and constraints?
2.  **Analyze Current Content:** Read the provided content carefully.
3.  **Identify Discrepancies:** Look for accuracy issues, completeness gaps, and clarity problems.
4.  **Propose Specific Improvements:** Propose concrete solutions for each weakness.
5.  **Generate Revised Content:** Rewrite the content incorporating all changes.

Original Prompt: "{original_prompt}"
Current Content: "{current_content}"

Please provide your internal 'Correction Thoughts' followed by 'Revised Content'.
"""

Note how this echoes the Reflection pattern from earlier in the series — but here it’s framed as a reasoning step, not a separate critic agent. The content gets measured against the original constraints (“max 150 chars”, a specific brand voice), which is exactly the check a single generation pass tends to skip.

3. Reasoning as a graph (Deep Search) — The hardest problems need a loop, not a line. The chapter’s Deep Search example models reasoning as a LangGraph state machine: generate queries, research, reflect on whether the findings are sufficient, and conditionally loop back or finalize:

class OverallState(TypedDict):
    query: str
    search_queries: List[str]
    research_results: List[str]
    reflection: str
    final_answer: str

def build_deep_search_graph():
    builder = StateGraph(OverallState)

    builder.add_node("generate_query", generate_query)
    builder.add_node("web_research", web_research)
    builder.add_node("reflection", reflection)
    builder.add_node("finalize_answer", finalize_answer)

    builder.add_edge(START, "generate_query")
    builder.add_conditional_edges("generate_query", lambda s: "web_research")
    builder.add_edge("web_research", "reflection")

    # The reasoning loop: reflect, then decide to research more or finish
    builder.add_conditional_edges(
        "reflection",
        evaluate_research,
        {"web_research": "web_research", "finalize_answer": "finalize_answer"}
    )
    builder.add_edge("finalize_answer", END)

    return builder.compile()

The reflection node feeding a conditional edge is the whole point. evaluate_research inspects the current state and returns either "web_research" (loop, I don’t have enough yet) or "finalize_answer" (good enough, ship it). That conditional self-evaluation is reasoning expressed as control flow.

4. Reasoning by delegation (multi-agent) — Sometimes “reason about this” means “route to the right kind of thinking.” The chapter’s multi-agent example classifies the question, then sends it to a specialist:

def route_to_agent(state: ReasoningState) -> Literal["search_agent", "code_agent"]:
    if state["agent_type"] == "code":
        return "code_agent"
    return "search_agent"

def build_reasoning_graph():
    builder = StateGraph(ReasoningState)
    builder.add_node("classify_question", classify_question)
    builder.add_node("search_agent", search_agent)
    builder.add_node("code_agent", code_agent)
    builder.add_node("synthesize_answer", synthesize_answer)

    builder.add_edge(START, "classify_question")
    builder.add_conditional_edges(
        "classify_question", route_to_agent,
        {"search_agent": "search_agent", "code_agent": "code_agent"}
    )
    builder.add_edge("search_agent", "synthesize_answer")
    builder.add_edge("code_agent", "synthesize_answer")
    builder.add_edge("synthesize_answer", END)

    return builder.compile()

A factual question (“differences between TCP and UDP”) goes to the search specialist; a computational one (“compound interest on $10,000 at 5% over 10 years”) goes to the code specialist. The reasoning here is the meta-decision — knowing which mode of thought the problem demands before committing to it.

Why This Matters
#

Reasoning Techniques is the pattern that turns an LLM from an autocomplete engine into something that can be trusted with multi-step work:

  • Math, logic, and code: anywhere a wrong intermediate step poisons the final answer, CoT plus self-correction is the floor, not a nice-to-have.
  • Deep research agents: the reflect-and-loop graph is what separates a one-shot answer from an agent that keeps digging until it actually has enough.
  • Quality-gated generation: marketing copy, contracts, summaries — anything with hard constraints — benefits from a self-correction pass that checks the output against the original spec.
  • Mixed workloads: classify-then-route lets one entry point handle both “what is” and “compute this” without a monolithic mega-prompt.

The cost? Tokens and latency, multiplied. Every one of these techniques trades a single call for several. CoT inflates the output. Self-correction at least doubles the work. The Deep Search loop can run an unbounded number of iterations if your evaluate_research logic is sloppy — which is exactly why this pattern lives right next to Resource-Aware Optimization. You reason more when the problem is hard, and you need an off-ramp so the loop terminates.

Two honest caveats. First, more reasoning steps mean more surface area for the model to talk itself into a confident wrong answer — a flawed chain-of-thought can launder a bad conclusion into something that looks rigorous. Second, none of this is free reliability: a self-correction pass can introduce regressions as easily as fixes. Log the intermediate steps, cap the loops, and evaluate the end-to-end result, not the prettiness of the reasoning trace.

Rule of thumb: reach for reasoning techniques when the failure mode is “plausible but wrong,” not when it’s “doesn’t know.” If the model lacks the knowledge, you need retrieval (Chapter 14). If it has the knowledge but botches the logic, you need to make it think.


The Bigger Picture
#

This is post #17 in my series documenting Antonio Gulli’s Agentic Design Patterns. All credit for the conceptual work goes to him — I’m focused on producing clean, runnable Python implementations that you can clone, modify, and ship.

What makes Reasoning Techniques interesting is that it’s less a single pattern and more the connective tissue under almost everything else in the book. Reflection (Chapter 4) is a reasoning loop. Planning (Chapter 6) is reasoning about future actions. The Deep Search graph here is Parallelization and Planning wearing a reasoning hat. Once you see “make the model think in structured steps” as a primitive, you start composing it everywhere.

All the code from this post is in my repository: carlosprados/Agentic_Design_Patterns, specifically under 17_Reasoning_Techniques/. The CoT and self-correction prompts run standalone, and the two LangGraph examples (langgraph_deep_search.py and langgraph_reasoning_agents.py) run with uv run, using the shared get_llm() abstraction that supports Gemini and Ollama.


What’s Next
#

In the next post we’ll tackle Guardrails / Safety Patterns — the techniques that keep a reasoning agent from reasoning its way into something harmful, off-policy, or just plain wrong. Because the more autonomy and reasoning power you hand an agent, the more it matters that there’s a fence around what it’s allowed to do.

Stay tuned.