Documentation Index Fetch the complete documentation index at: https://afk.arpan.sh/llms.txt
Use this file to discover all available pages before exploring further.
This tutorial expands the quickstart into the core workflow used by most AFK applications. Each section introduces one concept and keeps the code small enough to copy into a single file.
1. Agent + runner
from afk.agents import Agent
from afk.core import Runner
agent = Agent(
name = "tutor" ,
model = "gpt-4.1-mini" ,
instructions = "Explain programming concepts in plain language." ,
)
runner = Runner()
result = runner.run_sync(agent, user_message = "What is recursion?" )
print (result.final_text)
print (result.run_id)
Key point: an agent is declarative. The runner owns execution.
from pydantic import BaseModel
from afk.agents import Agent
from afk.core import Runner
from afk.tools import tool
class LookupArgs ( BaseModel ):
topic: str
max_results: int = 3
@tool ( args_model = LookupArgs, name = "search_docs" , description = "Search docs by topic." )
def search_docs ( args : LookupArgs) -> dict :
return {
"results" : [
{ "title" : f "Guide: { args.topic } " , "score" : 0.95 },
{ "title" : f "FAQ: { args.topic } " , "score" : 0.82 },
][: args.max_results]
}
agent = Agent(
name = "research-tutor" ,
model = "gpt-4.1-mini" ,
instructions = "Search docs before answering user questions." ,
tools = [search_docs],
)
result = Runner().run_sync(
agent,
user_message = "How do I handle errors in Python?" ,
)
print (result.final_text)
print (result.tool_executions)
Key point: tool arguments are validated before your function runs.
3. Streaming
Use streaming when a UI or CLI should show progress before the final result is ready.
import asyncio
from afk.agents import Agent
from afk.core import Runner
agent = Agent(
name = "streamer" ,
model = "gpt-4.1-mini" ,
instructions = "Explain topics clearly." ,
)
async def main () -> None :
handle = await Runner().run_stream(
agent,
user_message = "Explain Python decorators in three bullets." ,
)
async for event in handle:
if event.type == "text_delta" :
print (event.text_delta, end = "" , flush = True )
elif event.type == "completed" :
print ( f " \n\n state= { event.result.state } " )
asyncio.run(main())
Key point: run_stream() returns an AgentStreamHandle. Consume it to receive text, tool lifecycle events, errors, and the terminal result.
4. Memory continuity
Pass the same thread_id to keep conversation context attached to a thread.
import asyncio
from afk.agents import Agent
from afk.core import Runner
agent = Agent(
name = "memory-tutor" ,
model = "gpt-4.1-mini" ,
instructions = "Remember the user's earlier questions in this thread." ,
)
async def main () -> None :
runner = Runner()
thread_id = "student-session-42"
first = await runner.run(
agent,
user_message = "What are Python decorators?" ,
thread_id = thread_id,
)
second = await runner.run(
agent,
user_message = "Give me a short example using that idea." ,
thread_id = thread_id,
)
print (first.final_text)
print (second.final_text)
asyncio.run(main())
Key point: thread continuity is explicit. Use the same thread_id for related turns.
5. Safety limits
Production agents need hard limits even when prompts and tools are well designed.
from afk.agents import Agent, FailSafeConfig
from afk.core import Runner, RunnerConfig
agent = Agent(
name = "bounded-agent" ,
model = "gpt-4.1-mini" ,
instructions = "Help users, but stop if the task becomes too large." ,
fail_safe = FailSafeConfig(
max_steps = 8 ,
max_llm_calls = 12 ,
max_tool_calls = 20 ,
max_wall_time_s = 45.0 ,
max_total_cost_usd = 0.25 ,
),
)
runner = Runner(
config = RunnerConfig(
sanitize_tool_output = True ,
tool_output_max_chars = 8_000 ,
),
)
result = runner.run_sync(agent, user_message = "Summarize the tradeoffs of caching." )
print (result.final_text)
Key point: limits are part of the agent contract. Set them before shipping.
What to read next
Agents Agent fields, prompt resolution, subagents, skills, and MCP tools.
Tools Tool schemas, context, hooks, middleware, sandboxing, and output limits.
Streaming Event types, stream handles, cancellation, and UI patterns.
Production Readiness Evals, telemetry, security controls, queues, and deployment.