Build an AI Agent from Scratch with Python for M&E Workflows
Build an AI Agent from Scratch with Python for M&E Workflows
Learn how AI agents work and how the same architecture can be adapted for practical Monitoring, Evaluation, Research, and Learning workflows.
Practical EvalCommunity Tutorial
What You Will Learn
AI agents can do more than generate text. An agent can decide what information it needs, call a tool, inspect the result, perform another action, and continue until a task is completed.
- Retrieve information
- Calculate indicator values
- Check programme data
- Use external tools
- Combine results
- Produce a final explanation
Before You Start
This tutorial is intended for people with basic Python knowledge. You do not need to know LangChain, LangGraph, LlamaIndex, or another agent framework.
- Python 3
- An API key for your model provider
- A text editor or IDE
- Basic Python knowledge
1. What Makes Something an AI Agent?
A normal chatbot generally follows:
An agent introduces a decision-making loop:
For example, if you ask:
An agent can:
- Determine that it needs the current time.
- Call a time tool.
- Receive the result.
- Extract the hour.
- Call a calculation tool.
- Return the final answer.
2. The Four Components of an AI Agent
1. Perception
The agent receives information such as user questions, datasets, API responses, documents, or database records.
2. Reasoning
The model determines what should happen next and which action may be required.
3. Tool Use
Tools allow the agent to interact with calculations, data, documents, APIs, and other systems.
4. Memory
The agent maintains information about previous actions, observations, and the current task.
3. Understanding the ReAct Pattern
A simple way to understand an agent is:
The workflow is:
↓
Reason
↓
Choose Tool
↓
Execute Tool
↓
Observe Result
↓
Reason Again
↓
Final Answer
4. Create the Agent’s Data Structures
Start by defining the objects that represent messages, tools, actions, and agent state.
from dataclasses import dataclass, field
from typing import List, Callable, Dict, Any, Optional
@dataclass
class Message:
role: str
content: str
@dataclass
class Tool:
name: str
description: str
func: Callable
parameters: Dict[str, Any]
@dataclass
class Action:
action_name: Optional[str] = None
action_input: Optional[str] = None
@dataclass
class AgentState:
messages: List[Message] = field(default_factory=list)
step_count: int = 05. Connect Python to an LLM
The original source demonstrates a framework-free HTTP approach. For a current OpenAI implementation, a simple example is:
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5",
input="Explain what an AI agent is in two sentences."
)
print(response.output_text)6. Give the Agent Tools
Tools are controlled functions that allow an agent to perform specific operations.
Tool 1: Current Time
import datetime
def get_current_time():
return datetime.datetime.now(
datetime.timezone.utc
).isoformat()Tool 2: Calculator
import re
def calculate(expression: str) -> str:
if not re.match(
r'^[\d\s\+\-\*\/\(\)\.]+$',
expression
):
return "Error: invalid expression."
try:
return str(eval(expression))
except Exception as e:
return f"Error: {e}"eval(), exec(), shell commands, databases, or sensitive files.Register the Tools
time_tool = Tool(
name="get_current_time",
description="Returns the current time in UTC.",
func=get_current_time,
parameters={}
)
math_tool = Tool(
name="calculate",
description="Calculates a basic mathematical expression.",
func=calculate,
parameters={"expression": "string"}
)
AVAILABLE_TOOLS = {
"get_current_time": time_tool,
"calculate": math_tool
}7. Build the Agent Execution Loop
The core loop is:
for step in range(max_steps):
ask the model what to do
if it wants to finish:
return final answer
identify the requested tool
validate the request
execute the tool
store the result
continueYour application should remain responsible for validating and executing the requested action.
8. Why a Maximum Step Count Matters
Agents can get stuck in loops:
Use a maximum number of steps:
MAX_STEPS = 59. The Agent in Action
Consider:
USER: What is the current UTC hour, and multiply it by 14?
AGENT: I need the current time.
TOOL: get_current_time()
RESULT: 2026-03-02T09:15:30Z
AGENT: The hour is 9. I need to calculate 9 × 14.
TOOL: calculate(“9 * 14”)
RESULT: 126
FINAL: The current UTC hour is 9 and 9 × 14 = 126.
10. Apply the Architecture to M&E
Imagine building an Indicator Monitoring Agent.
Instead of giving the model unrestricted access to your system, define specific tools:
get_indicator_target()
get_latest_value()
calculate_achievement()
generate_status()
↓
Retrieve Data
↓
Calculate
↓
Assess Status
↓
Explain Result
11. Example: Indicator Achievement Agent
Suppose:
| Measure | Value |
|---|---|
| Target | 80% |
| Current value | 68% |
def calculate_achievement(current, target):
return (current / target) * 100The result would be:
Current value: 68%
Target: 80%
The AI can then explain the result in natural language while Python handles the calculation.
12. Examples of M&E Agents
Data Quality Agent
read_dataset() → check_missing_values() → check_duplicates() → summarise_quality()
Evidence Agent
search_documents() → retrieve_evidence() → compare_findings() → summarise_evidence()
Reporting Agent
get_results() → identify_variances() → draft_report_section()
Beneficiary Feedback Agent
load_feedback() → classify_feedback() → identify_themes() → summarise_findings()
13. Agent vs. Chatbot
| Chatbot | AI Agent |
|---|---|
| Generates responses | Performs workflows |
| Limited external interaction | Can call tools |
| Mostly conversational | Task-oriented |
| Usually passive | Can select actions |
| Limited workflow state | Maintains state and observations |
14. When Should You NOT Use an Agent?
Agents add complexity. A normal scripted workflow may be better when:
- The steps are always identical.
- The calculations are deterministic.
- There are few decisions.
- The process does not require model judgment.
- Reliability is more important than flexibility.
Load CSV → Calculate percentage → Save result
Identify evidence needed → Select tools → Inspect results → Identify gaps → Retrieve additional evidence → Produce synthesis
15. Memory and Context Management
As an agent runs, its context grows with requests, tool calls, results, and observations.
For longer workflows, consider summarising older information while preserving:
- The original evaluation question
- Important assumptions
- Key evidence
- Important tool results
- Decisions already made
- Unresolved issues
16. Structured Outputs
A basic educational implementation might parse text such as:
Action: calculate
Action Input: {"expression": "9 * 14"}This can be fragile. Production systems should use structured tool calls and validated schemas wherever supported.
17. Add Guardrails
Tool Allow-List
Only expose tools the agent actually needs.
Parameter Validation
Validate every argument before executing a tool.
Maximum Steps
Prevent the agent from running indefinitely.
Permission Boundaries
Separate read, write, and delete permissions.
Human Review
Keep human review for consequential decisions such as evaluation conclusions, donor reporting, sensitive classifications, and decisions based on incomplete evidence.
18. A Practical M&E Agent Architecture
↓
AI Agent
↓
Data Tools | Evidence Tools | Analysis Tools
↓
Validation
↓
Human Review
↓
Final Output
The agent is therefore a system architecture, not simply a prompt.
19. Production Improvements
- Structured tool calls: Avoid fragile text parsing.
- Logging: Record important actions and results.
- Retries: Handle temporary failures.
- Validation: Check tool results.
- Human approval: Review high-impact actions.
- Evaluation: Test accuracy, tool selection, and failure rates.
The Most Important Lesson
The most important lesson is understanding the separation between the model, tools, state, executor, and human oversight.
The goal is not to make AI autonomous for the sake of autonomy. The goal is to create controlled, auditable workflows where AI can decide which step to take while deterministic tools, validation rules, and human oversight control what the system is actually allowed to do.
Practical Exercise: Build an M&E Agent
Create three tools:
get_target()
calculate_achievement()
Then ask:
The agent should:
- Identify the indicator.
- Retrieve the current value.
- Retrieve the target.
- Calculate achievement.
- Assess the result.
- Explain the conclusion.
- Identify missing information.
Challenge: Add an Evidence Tool
Add a tool such as:
def search_evidence(topic):
...Then ask:
Key Concepts
| Concept | Meaning |
|---|---|
| AI Agent | A system that can use tools and perform multiple steps. |
| Tool | A controlled function the agent can call. |
| State | Information retained during the task. |
| ReAct | Reason → Act → Observe → Repeat. |
| Guardrail | A restriction controlling what the agent can do. |
| Human-in-the-loop | Human review of important decisions or actions. |
Suggested Next Step
Replace the calculator and time tools with three tools from an actual M&E workflow you perform regularly.
Which parts require judgment, and which should remain deterministic?
