Skip to content

Commit 7c62b28

Browse files
author
AgentPatterns
committed
feat(examples/python): add write-your-first-agent runnable example
1 parent 638b71a commit 7c62b28

8 files changed

Lines changed: 211 additions & 2 deletions

File tree

.github/workflows/python.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Python Examples CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
check-python-examples:
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Set up Python
15+
uses: actions/setup-python@v5
16+
with:
17+
python-version: "3.11"
18+
19+
- name: Find and check all Python examples
20+
run: |
21+
set -e
22+
23+
if [ ! -d "examples" ]; then
24+
echo "No examples/ directory. Skipping."
25+
exit 0
26+
fi
27+
28+
echo "Searching for Python examples..."
29+
30+
for dir in $(find examples -type f -name "main.py" -exec dirname {} \;); do
31+
echo "=============================="
32+
echo "Checking example in: $dir"
33+
cd $dir
34+
35+
if [ -f "requirements.txt" ]; then
36+
pip install -r requirements.txt
37+
fi
38+
39+
echo "Compiling Python files..."
40+
python -m compileall .
41+
42+
cd - > /dev/null
43+
done
44+

.gitignore

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# -------------------------
2+
# Python
3+
# -------------------------
4+
__pycache__/
5+
*.py[cod]
6+
*$py.class
7+
*.so
8+
*.pyd
9+
*.pyo
10+
11+
# Virtual environments
12+
.venv/
13+
venv/
14+
env/
15+
ENV/
16+
17+
# Distribution / packaging
18+
build/
19+
dist/
20+
*.egg-info/
21+
.eggs/
22+
23+
# Logs
24+
*.log
25+
26+
# Environment variables
27+
.env
28+
.env.*
29+
!.env.example
30+
31+
# Pytest / coverage
32+
.pytest_cache/
33+
.coverage
34+
htmlcov/
35+
.cache/
36+
37+
# IDEs
38+
.vscode/
39+
.idea/
40+
41+
# OS
42+
.DS_Store
43+
Thumbs.db
44+
45+
# Jupyter
46+
.ipynb_checkpoints/
47+
48+
# MyPy / Ruff
49+
.mypy_cache/
50+
.ruff_cache/
51+
52+
# Local runtime files
53+
*.sqlite3
54+
*.db
55+

README.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,36 @@
1-
# Agentpatterns Examples
2-
Runnable examples for AgentPatterns.tech articles (safe agent loops, budgeting, tool calling demos).
1+
# AgentPatterns Examples
2+
3+
Runnable code examples that accompany articles on [agentpatterns.tech](https://www.agentpatterns.tech).
4+
5+
This repository is a practical companion to the main project: each article can include a small, focused example you can run locally and adapt for your own use cases.
6+
7+
## What lives here
8+
9+
- `examples/` contains article-aligned examples.
10+
- Each example is grouped by topic, then by language/runtime.
11+
- Examples are intentionally minimal: clear logic, fast setup, easy to remix.
12+
13+
## Current structure
14+
15+
```text
16+
examples/
17+
write-your-first-agent/
18+
python/
19+
```
20+
21+
## Quick start (Python example)
22+
23+
```bash
24+
cd examples/write-your-first-agent/python
25+
python3 -m venv .venv
26+
source .venv/bin/activate
27+
pip install -r requirements.txt
28+
export OPENAI_API_KEY="sk-..."
29+
python main.py
30+
```
31+
32+
## Relation to agentpatterns.tech
33+
34+
- Articles explain concepts and patterns.
35+
- This repo provides runnable implementations for those materials.
36+
- As new articles are published, matching examples are added here.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
📖 Based on article:
2+
3+
EN:
4+
https://agentpatterns.tech/en/start-here/write-your-first-agent
5+
6+
DE:
7+
https://agentpatterns.tech/de/start-here/write-your-first-agent
8+
9+
FR:
10+
https://agentpatterns.tech/fr/start-here/write-your-first-agent
11+
12+
ES:
13+
https://agentpatterns.tech/es/start-here/write-your-first-agent
14+
15+
UK:
16+
https://agentpatterns.tech/uk/start-here/write-your-first-agent
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
def parse_int(text: str) -> int | None:
2+
"""Returns int or None if the text is not a valid integer."""
3+
try:
4+
return int(text.strip())
5+
except (ValueError, AttributeError):
6+
return None
7+
8+
def is_goal_reached(number: int, goal: int) -> bool:
9+
"""Returns True if the number satisfies the goal condition."""
10+
return number > goal
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import os
2+
from openai import OpenAI
3+
4+
api_key = os.environ.get("OPENAI_API_KEY")
5+
6+
if not api_key:
7+
raise EnvironmentError(
8+
"OPENAI_API_KEY is not set.\n"
9+
"Run: export OPENAI_API_KEY='sk-...'"
10+
)
11+
12+
client = OpenAI(api_key=api_key)
13+
14+
PROMPT = "Write ONLY a random number between 1 and 20. No text, no explanation."
15+
16+
def generate_number() -> str:
17+
resp = client.responses.create(
18+
model="gpt-4.1-mini",
19+
input=PROMPT,
20+
)
21+
return resp.output_text.strip()
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from llm import generate_number
2+
from evaluator import parse_int, is_goal_reached
3+
4+
GOAL = 10
5+
MAX_STEPS = 5
6+
7+
def run():
8+
for step in range(1, MAX_STEPS + 1):
9+
print(f"\n🤖 Step {step}: Agent is trying...")
10+
11+
output = generate_number()
12+
print(f"💬 Model generated: {output}")
13+
14+
number = parse_int(output)
15+
if number is None:
16+
print("❌ Not a number. Trying again...")
17+
continue
18+
19+
if is_goal_reached(number, GOAL):
20+
print(f"✅ Goal reached! {number} > {GOAL}")
21+
return
22+
23+
print(f"❌ Not enough. {number}{GOAL}. Trying again...")
24+
25+
print("\n⚠️ Max steps reached without success")
26+
27+
if __name__ == "__main__":
28+
run()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
openai>=1.0.0

0 commit comments

Comments
 (0)