This document provides comprehensive instructions for coding agents working on this repository. Following these instructions will help you work more efficiently and avoid common pitfalls.
This repository contains a collection of Python scripts that demonstrate how to use the OpenAI Responses API (and compatible APIs like Azure OpenAI and Ollama). The repository includes examples of:
- Basic responses (streaming, async, history)
- Function calling (basic to advanced multi-function scenarios)
- Structured outputs using Pydantic models
- Retrieval-Augmented Generation (RAG) with various complexity levels
- Prompt engineering and safety features
The scripts are designed to be educational and can run with multiple LLM providers: Azure OpenAI (preferred), OpenAI.com, or local Ollama models.
All example scripts are located in the root directory. They follow a consistent pattern of setting up an OpenAI client based on environment variables, then demonstrating specific API features.
Chat Scripts:
chat.py- Simple response examplechat_stream.py- Streaming responseschat_async.py- Async responses withasyncio.gatherexampleschat_history.py- Multi-turn chat with message historychat_history_stream.py- Multi-turn chat with streamingchat_safety.py- Content safety filter exception handling
Function Calling Scripts:
function_calling_basic.py- Single function declaration, prints tool calls (no execution)function_calling_call.py- Executes the function once if the model requests itfunction_calling_extended.py- Full round-trip: executes, returns tool output, gets final answerfunction_calling_errors.py- Same as extended but with robust error handling (malformed JSON args, missing tool, tool exceptions, JSON serialization)function_calling_parallel.py- Shows model requesting multiple tools in one responsefunction_calling_while_loop.py- Conversation loop that keeps executing sequential tool calls until the model produces a final natural language answer (with error handling)
Structured Outputs Scripts:
structured_outputs_basic.py- Basic Pydantic model extractionstructured_outputs_description.py- Using field descriptionsstructured_outputs_enum.py- Restricting values with enumsstructured_outputs_function_calling.py- Combining function calling with Pydanticstructured_outputs_nested.py- Nested Pydantic models
RAG Scripts (require requirements-rag.txt):
rag_csv.py- RAG with CSV file retrievalrag_multiturn.py- RAG with multi-turn chat interfacerag_queryrewrite.py- RAG with query rewriting steprag_documents_ingestion.py- PDF ingestion (uses pymupdf, langchain, creates JSON)rag_documents_flow.py- RAG flow using ingested documentsrag_documents_hybrid.py- Hybrid retrieval with vector + keyword search + RRF + reranking
Other Scripts:
prompt_engineering.py- Prompt engineering examplesreasoning.py- Reasoning exampleschained_calls.py- Chained API callsretrieval_augmented_generation.py- Alternative RAG example
The spanish/ directory contains Spanish translations of most example scripts and a Spanish README. The Python scripts are functionally equivalent to their English counterparts.
The data/ directory contains PDF files used by the RAG document ingestion examples:
Aphideater_hoverfly.pdfCalifornia_carpenter_bee.pdfCentris_pallida.pdfWestern_honey_bee.pdf
Bicep Infrastructure as Code:
infra/main.bicep- Defines Azure OpenAI resource provisioning with GPT-4o and embedding modelsinfra/main.parameters.json- Parameters for Bicep deployment
Environment Setup Scripts:
infra/write_dot_env.sh- Shell script to create.envfrom azd environment (Linux/Mac)infra/write_dot_env.ps1- PowerShell script to create.envfrom azd environment (Windows)
These scripts are automatically run by azd provision via the azure.yaml postprovision hooks.
Python Configuration:
pyproject.toml- Ruff and Black linter/formatter configuration (line-length: 120, target: py311)requirements.txt- Core dependencies:azure-identity,openai>=1.108.1,python-dotenv,langchain-text-splittersrequirements-rag.txt- RAG-specific dependencies:pymupdf4llm,lunr,sentence-transformersrequirements-dev.txt- Development dependencies: includes requirements.txt + requirements-rag.txt +pre-commit,ruff,black
Pre-commit Configuration:
.pre-commit-config.yaml- Pre-commit hooks for check-yaml, end-of-file-fixer, trailing-whitespace, ruff, and black
Azure Developer CLI:
azure.yaml- Defines azd hooks (postprovision scripts)
Environment Variables:
.env.sample- Example .env file showing all possible configurations.env.sample.azure- Azure-specific example.env.sample.ollama- Ollama example.env.sample.openai- OpenAI.com example
python.yaml - Linting and Formatting Check:
- Runs on: push to main, pull requests to main
- Uses: uv for virtual environment and dependency installation
- Runs:
uv run ruff check .anduv run black . --check --verbose - Important: The CI uses
uvbut local development typically uses standardpip
.devcontainer/devcontainer.json- Default dev container (Azure OpenAI setup with azd).devcontainer/Dockerfile- Base Python 3.12 image, installs all requirements-dev.txt.devcontainer/ollama/- Ollama variant.devcontainer/openai/- OpenAI.com variant
All dev containers install all dependencies from requirements-dev.txt which includes base, RAG, and dev tools.
ALWAYS follow these steps in order:
-
Create a Python virtual environment (if not in a Dev Container or Codespaces):
python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate
-
Install base dependencies:
python -m pip install -r requirements.txt
-
For RAG examples, ALSO install RAG dependencies:
python -m pip install -r requirements-rag.txt
-
For development (linting, formatting), install dev dependencies:
python -m pip install -r requirements-dev.txt
Note:
requirements-dev.txtincludes bothrequirements.txtandrequirements-rag.txtvia-rdirectives.
The scripts read environment variables from a .env file. Create one based on your provider:
For agents: Check if Azure OpenAI environment variables are already configured:
if [ -n "$AZURE_OPENAI_ENDPOINT" ] && [ -n "$AZURE_OPENAI_CHAT_DEPLOYMENT" ]; then
echo "Azure OpenAI available - required environment variables are set"
else
echo "Azure OpenAI not available - missing AZURE_OPENAI_ENDPOINT or AZURE_OPENAI_CHAT_DEPLOYMENT"
fiIf Azure OpenAI variables are not available, an administrator would need to provision Azure resources using:
azd auth login
azd provisionThis creates real Azure resources that incur costs. The .env file would be created automatically with all needed variables after provisioning.
For agents: Check if OpenAI.com API key is available:
if [ -n "$OPENAI_API_KEY" ]; then
echo "OpenAI.com available - OPENAI_API_KEY is set"
else
echo "OpenAI.com not available - OPENAI_API_KEY not found"
fiIf OPENAI_API_KEY is available, ensure API_HOST=openai and OPENAI_MODEL are also set (e.g., gpt-4o-mini).
For agents: Check if Ollama is installed and running:
if command -v ollama &> /dev/null; then
echo "Ollama command found"
ollama list
if [ $? -eq 0 ]; then
echo "Ollama is running and available"
else
echo "Ollama installed but not running"
fi
else
echo "Ollama not installed"
fiIf Ollama is available, configure the environment:
# API_HOST=ollama
# OLLAMA_ENDPOINT=http://localhost:11434/v1
# OLLAMA_MODEL=llama3.1Important: If running in a Dev Container, use http://host.docker.internal:11434/v1 instead of localhost.
After environment setup and .env configuration, run any script:
python chat.py
python function_calling_basic.py
python rag_csv.py # Requires requirements-rag.txt to be installedFor Spanish versions:
python spanish/chat.py# After installing requirements-dev.txt
ruff check .To auto-fix issues:
ruff check . --fixCheck formatting:
black . --check --verboseAuto-format:
black .Install pre-commit hooks to automatically run checks before commits:
pre-commit installRun manually:
pre-commit run --all-filesThe repository has limited automated testing via GitHub Actions. Changes to scripts should be manually verified by running them:
python chat.py
python spanish/chat.pyNote: Most scripts are demonstration scripts, not unit-tested. Changes to scripts should be manually verified by running them.
- All scripts default to
API_HOST=azureif no .env file is present and no environment variable is set. - Scripts use
load_dotenv(override=True)which means .env values override environment variables.
- Function calling scripts require models that support tools. Not all models support this:
- ✅ Supported:
gpt-4o,gpt-4o-mini,gpt-5.4, and many others - ❌ Not supported: Older models, some local Ollama models
- ✅ Supported:
- If a script fails with a function calling error, check if your model supports the
toolsparameter.
- RAG scripts require
requirements-rag.txtto be installed. They will fail with import errors if these dependencies are missing. - The
rag_documents_ingestion.pyscript createsrag_ingested_chunks.json(large file, ~6MB) which is used byrag_documents_flow.pyandrag_documents_hybrid.py. - The ingestion process requires the PDF files in the
data/directory.
- Dev containers automatically install all dependencies from
requirements-dev.txtduring build. - Azure-focused dev container includes
azure-cliandazdfeatures. - The default dev container expects Azure OpenAI configuration.
- Line length is 120 characters (configured in
pyproject.toml). - Target Python version is 3.11 (though 3.12 is used in dev containers).
- Ruff is configured to check: E (errors), F (pyflakes), I (isort), UP (pyupgrade).
- Black and Ruff should both pass for CI to succeed.
- CI uses
uvfor faster installation:uv venv .venv && uv pip install -r requirements-dev.txt - Local development typically uses
pip:python -m venv .venv && python -m pip install -r requirements-dev.txt - Both approaches work, but
uvis faster for CI.
- Running
azd provisioncreates real Azure resources that incur costs. - The infrastructure creates:
- Azure OpenAI account with
gpt-4odeployment (capacity: 30) - Text embedding deployment
text-embedding-3-small(capacity: 30)
- Azure OpenAI account with
- The postprovision hook automatically creates the
.envfile. - Always run
azd downwhen done to avoid ongoing charges.
- Spanish translations are in
spanish/directory with their own README and scripts. - Spanish scripts are functionally identical to English versions, just translated.
- Both English and Spanish directories have their own
rag_ingested_chunks.jsonfiles.
Error: ImportError: No module named 'pymupdf4llm'
- Solution: Install RAG dependencies:
python -m pip install -r requirements-rag.txt
Error: KeyError: 'AZURE_OPENAI_ENDPOINT'
- Solution: Your
.envfile is missing required Azure variables, orAPI_HOSTis set toazurebut you haven't configured Azure. Runazd provisionor configure Azure properly.
Error: openai.APIError: content_filter
- This is expected behavior for
chat_safety.py- it's demonstrating content filtering. - The script catches this error and prints a message.
Error: Function calling not supported
- Solution: Use a model that supports tools, such as
gpt-4o,gpt-4o-mini, orgpt-5.4.
Error: azd command not found
- Solution: Install Azure Developer CLI: https://aka.ms/install-azd
When making code changes:
- Always install dependencies first:
python -m pip install -r requirements-dev.txt - Run linters before making changes to understand baseline:
ruff check .andblack . --check - Make minimal, surgical changes to the relevant scripts.
- Run linters again after changes:
ruff check .andblack .(auto-fix) - Manually test the changed script:
python your_modified_script.py
- Check that Spanish translations are updated if applicable.
These instructions have been validated by:
- Reviewing all documentation (README.md, CONTRIBUTING.md)
- Examining all configuration files (pyproject.toml, .pre-commit-config.yaml, azure.yaml)
- Analyzing all CI/CD workflows (.github/workflows/)
- Inspecting all infrastructure files (infra/)
- Testing environment setup and linting commands
- Verifying dependency installation processes
If you encounter discrepancies between these instructions and the actual repository state, the repository may have been updated. In that case:
- Re-examine the relevant documentation or configuration files
- Update these instructions if needed
- Otherwise, trust these instructions and only explore further if they are incomplete or proven incorrect