HOW-TO · RAG

How to Create Agent Decision-Making Logic

advanced25 minBy Fredoline Eruo
Target environment
Ubuntu 24.04 · Ollama 0.4.x
PREREQUISITES

Agent with basic tool use working, Python 3.10+

What this does

Decision-making logic determines which tool to call, in what order, and when to stop. This goes beyond simple ReAct loops by adding planning, prioritization, and self-evaluation.

Steps

  • Implement a planner step. Before any tool calls, generate a plan with ordered steps.
def generate_plan(user_input: str, available_tools: list[str]) -> list[str]:
    prompt = f"""Given the task: '{user_input}'
Available tools: {', '.join(available_tools)}
Create a step-by-step plan. Return one step per line."""
    response = llm.invoke(prompt)
    return [s.strip() for s in response.content.split("\n") if s.strip()]
  • Add a priority scoring function. Evaluate tool options before choosing.
def score_tool(tool_name: str, task: str, context: dict) -> float:
    # Simple heuristic: prefer tools that match task keywords
    if tool_name in task.lower():
        return 0.9
    if "search" in task.lower() and "search" in tool_name:
        return 0.8
    return 0.5
  • Build a decision tree for tool selection. Use a router that maps intent to tool.
def route_intent_to_tool(intent: str) -> str:
    if any(w in intent for w in ["search", "find", "look up"]):
        return "search_web"
    elif any(w in intent for w in ["calculate", "math", "compute"]):
        return "calculate"
    elif any(w in intent for w in ["save", "write", "store"]):
        return "save_to_file"
    return "ask_clarification"
  • Implement self-evaluation after each step. The agent scores its own progress.
def evaluate_progress(messages: list, original_task: str) -> dict:
    eval_prompt = f"""Task: {original_task}
Recent actions: {messages[-3:]}
Rate progress (1-5) and state if task is complete. Return JSON with 'score' and 'done'."""
    response = llm.invoke(eval_prompt)
    return json.loads(response.content)
  • Handle uncertainty with clarification. If confidence is low, ask the user.
def should_clarify(user_input: str, context: dict) -> bool:
    prompt = f"""On a scale of 0-1, how confident are you that the user's intent is clear?
User input: {user_input}
Return only a number."""
    response = float(llm.invoke(prompt).content.strip())
    return response < 0.7

Verification

python -c "
# Test router
def route(intent):
    if 'search' in intent: return 'search_web'
    if 'calc' in intent: return 'calculate'
    return 'unknown'

print(route('search for python tutorials'))
# Expected: search_web
"

Common failures

  • Over-planner. The agent spends all its budget planning and never executes. Cap planning steps at 3-5.
  • Self-evaluation loop. The agent keeps evaluating without making progress. Only evaluate every N steps, not after every action.
  • Clarification fatigue. Asking for clarification on every ambiguous input frustrates users. Only clarify when confidence is below a threshold (e.g., 0.5).
  • Version mismatch - The installed package or runtime differs from the command shown; check the version first and rerun the smallest verification command.
  • Local environment drift - Another service, virtual environment, model, or path is being used; print the active binary path and configuration before changing the guide steps.

Related guides

  • How to Implement Tool Use in AI Agents
  • How to Build Multi-Agent Orchestration System