This directory contains a simple agent framework and test agent that were generated by GitHub Copilot using the prompts in the file prompt.md.
You will need an OpenAI API key to run the agent. The key should be set in the environment variable OPENAI_API_KEY.
Important: NEVER check your API key into GitHub!
We recommend using the direnv utility to manage your environment variables:
- Install direnv (follow instructions at https://direnv.net/)
- Copy the template:
cp envrc.template .envrc - Edit
.envrcand set your OpenAI API key - Run
direnv allowto activate the environment
The .envrc file is already in .gitignore to prevent accidental commits of your API key.
This project uses a Makefile to simplify setup and running:
make venvNote: You may need to adjust the BASE_PYTHON variable in the Makefile to point to the correct Python installation on your system.
Once you have your API key configured and the virtual environment set up, you can run the test agent:
# Basic usage
make run QUERY="what is 5 + 3 * 2"
# With verbose output
make run QUERY="calculate 15 / 3 + 4" VERBOSE=--verbose
# Or run directly
./venv/bin/python agent_test.py "what is 10 * 5 - 3"
./venv/bin/python agent_test.py --verbose "compute 100 / 4 + 6 * 2"The test script supports the following options:
--model NAME: Model to use (default: gpt-4o)--base-url URL: OpenAI base URL (default: https://api.openai.com/v1)--verbose: Enable detailed logging of LLM interactionsQUERY: The calculation query (required positional argument)
The agent framework (agent.py) provides a simple but powerful abstraction for building LLM-powered agents with tool use capabilities:
-
Agent Class: The main class that orchestrates the interaction between the LLM and tools
- Takes a system prompt, OpenAI credentials, model name, and a list of tool functions
- Manages the conversation loop with the LLM
- Handles tool execution and result formatting
-
Tool Schema Conversion: Uses Pydantic to automatically convert Python functions into OpenAI-compatible JSON schemas
- Extracts type annotations from function signatures
- Generates proper JSON schema with parameter types and descriptions
- Functions just need type hints and docstrings
-
Conversation Loop: Implements an iterative loop that:
- Sends messages to the LLM with available tools
- Receives responses that may include tool calls
- Executes requested tools and feeds results back to the LLM
- Continues until the LLM provides a final answer (up to max iterations)
-
Verbose Mode: When enabled, pretty-prints all messages, tool calls, and results for debugging and understanding agent behavior
- Type-safe tool definitions: Tools are just Python functions with type annotations
- Automatic schema generation: Pydantic handles conversion to OpenAI format
- Error handling: Gracefully handles tool execution errors
- Flexible: Works with any OpenAI-compatible API endpoint
The test agent (agent_test.py) demonstrates the framework by implementing a calculator agent:
Four basic arithmetic operations are provided as tools:
add(a, b): Additionsubtract(a, b): Subtractionmultiply(a, b): Multiplicationdivide(a, b): Division
Each tool takes two float parameters and returns a float result.
The agent is configured with a system prompt that instructs it to:
- Break down complex mathematical expressions into binary operations
- Follow the standard order of operations (PEMDAS)
- Use the available tools to compute each step
- Show its work by explaining the breakdown
When you ask the calculator agent "what is 5 + 3 * 2", it will:
- Recognize it needs to follow order of operations
- Call
multiply(3, 2)first to get 6 - Call
add(5, 6)to get the final result of 11 - Return the answer with an explanation
This demonstrates how the agent framework enables step-by-step reasoning and tool use to solve problems.