Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Builds AI agents using OpenAI Agents SDK with async/await patterns and multi-agent orchestration. Use when creating tutoring agents, building agent handoffs, implementing tool-calling agents, or orchestrating multiple specialists. Covers Agent class, Runner patterns, function tools, guardrails, and streaming responses. NOT when using raw OpenAI API without SDK or other agent frameworks like LangChain.
.claude/skills/aiskillstore-scaffolding-openai-agents/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 45% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 71% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 135% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 121% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 50% | 0% |
Build production AI agents using OpenAI Agents SDK with native async/await patterns.
bash# Project setup mkdir my-agent && cd my-agent python -m venv .venv && source .venv/bin/activate pip install openai-agents # Set API key export OPENAI_API_KEY=sk-...
python# main.py import asyncio from agents import Agent, Runner agent = Agent( name="Python Tutor", instructions="You help students learn Python. Explain concepts clearly with examples." ) async def main(): result = await Runner.run(agent, "Explain list comprehensions") print(result.final_output) asyncio.run(main())
pythonfrom agents import Agent tutor = Agent( name="Python Tutor", instructions="""You are an expert Python tutor. Explain concepts clearly with examples. Ask clarifying questions when needed. Provide practice exercises after explanations.""", model="gpt-4o" )
pythonfrom agents import Agent, ModelSettings agent = Agent( name="Creative Writer", instructions="Write creative stories based on prompts.", model="gpt-4o", model_settings=ModelSettings( temperature=0.9, max_tokens=2000 ) )
pythonfrom pydantic import BaseModel from agents import Agent class CodeReview(BaseModel): issues: list[str] suggestions: list[str] score: int reviewer = Agent( name="Code Reviewer", instructions="Review Python code for issues and improvements.", output_type=CodeReview # Forces structured JSON output )
pythonimport asyncio from agents import Agent, Runner async def main(): agent = Agent(name="Helper", instructions="Be helpful") # Single query result = await Runner.run(agent, "What is Python?") print(result.final_output) # With conversation history messages = [ {"role": "user", "content": "My name is Alex"}, {"role": "assistant", "content": "Nice to meet you, Alex!"}, {"role": "user", "content": "What's my name?"} ] result = await Runner.run(agent, messages) print(result.final_output) # "Your name is Alex" asyncio.run(main())
pythonfrom agents import Agent, Runner agent = Agent(name="Helper", instructions="Be helpful") result = Runner.run_sync(agent, "Hello!") print(result.final_output)
pythonimport asyncio from agents import Agent, Runner async def main(): agent = Agent(name="Storyteller", instructions="Tell engaging stories") result = Runner.run_streamed(agent, "Tell me a short story") async for event in result.stream_events(): if hasattr(event, 'delta'): print(event.delta, end='', flush=True) print() # Newline at end asyncio.run(main())
pythonasync def chat_session(): agent = Agent(name="Tutor", instructions="You are a Python tutor") # First turn result1 = await Runner.run(agent, "Explain decorators") print(f"Tutor: {result1.final_output}") # Continue conversation messages = result1.to_input_list() + [ {"role": "user", "content": "Show me an example"} ] result2 = await Runner.run(agent, messages) print(f"Tutor: {result2.final_output}")
pythonfrom agents import Agent, function_tool @function_tool def get_current_time() -> str: """Get the current time.""" from datetime import datetime return datetime.now().strftime("%H:%M:%S") @function_tool def calculate(expression: str) -> float: """Calculate a mathematical expression. Args: expression: A valid Python math expression like "2 + 2" or "10 * 5" """ return eval(expression) # Use safe_eval in production agent = Agent( name="Assistant", instructions="Help with calculations and time queries.", tools=[get_current_time, calculate] )
pythonimport httpx from agents import Agent, function_tool @function_tool async def fetch_weather(city: str) -> str: """Fetch current weather for a city. Args: city: The city name to get weather for """ async with httpx.AsyncClient() as client: response = await client.get( f"https://wttr.in/{city}?format=3" ) return response.text agent = Agent( name="Weather Bot", instructions="Provide weather information.", tools=[fetch_weather] )
pythonfrom pydantic import BaseModel from agents import Agent, function_tool class SearchQuery(BaseModel): query: str max_results: int = 10 class SearchResult(BaseModel): title: str url: str snippet: str @function_tool async def search_docs(params: SearchQuery) -> list[SearchResult]: """Search documentation for a query.""" # Implementation return [SearchResult( title="Python Tutorial", url="https://docs.python.org", snippet="Official Python documentation..." )] agent = Agent( name="Doc Search", instructions="Search Python documentation.", tools=[search_docs] )
pythonfrom agents import Agent, Runner # Specialist agents concepts_agent = Agent( name="Concepts Tutor", handoff_description="Explains Python concepts and fundamentals", instructions="Explain Python concepts clearly with examples." ) debug_agent = Agent( name="Debug Helper", handoff_description="Helps debug Python code errors", instructions="Help diagnose and fix Python errors." ) exercise_agent = Agent( name="Exercise Generator", handoff_description="Creates practice problems and exercises", instructions="Generate practice problems with solutions." ) # Triage agent with handoffs triage_agent = Agent( name="Triage", instructions="""Route student questions to the right specialist: - Concepts questions → Concepts Tutor - Error/bug questions → Debug Helper - Practice requests → Exercise Generator Analyze the question and hand off to the appropriate agent.""", handoffs=[concepts_agent, debug_agent, exercise_agent] ) async def main(): # Question gets routed automatically result = await Runner.run( triage_agent, "I'm getting a KeyError in my dictionary code" ) print(result.final_output) # Handled by debug_agent
pythonfrom agents import Agent, Runner # Create specialist agents researcher = Agent( name="Researcher", instructions="Research topics thoroughly." ) writer = Agent( name="Writer", instructions="Write clear, engaging content." ) # Manager uses agents as tools manager = Agent( name="Content Manager", instructions="""Coordinate research and writing: 1. Use researcher tool to gather information 2. Use writer tool to create content""", tools=[ researcher.as_tool( tool_name="research", tool_description="Research a topic" ), writer.as_tool( tool_name="write", tool_description="Write content about a topic" ) ] ) async def main(): result = await Runner.run( manager, "Create a blog post about async Python" ) print(result.final_output)
pythonfrom agents import Agent, input_guardrail, GuardrailFunctionOutput @input_guardrail async def check_homework_topic(context, agent, input_text: str) -> GuardrailFunctionOutput: """Ensure questions are homework-related.""" keywords = ["python", "code", "programming", "function", "class", "error"] if not any(kw in input_text.lower() for kw in keywords): return GuardrailFunctionOutput( output_info="Not a programming question", tripwire_triggered=True ) return GuardrailFunctionOutput( output_info="Valid programming question", tripwire_triggered=False ) tutor = Agent( name="Python Tutor", instructions="Help with Python homework.", input_guardrails=[check_homework_topic] )
pythonfrom agents import Agent, output_guardrail, GuardrailFunctionOutput @output_guardrail async def check_no_solutions(context, agent, output: str) -> GuardrailFunctionOutput: """Ensure we don't give complete homework solutions.""" solution_indicators = ["here's the complete", "full solution", "copy this code"] if any(ind in output.lower() for ind in solution_indicators): return GuardrailFunctionOutput( output_info="Contains complete solution", tripwire_triggered=True ) return GuardrailFunctionOutput( output_info="Output is appropriate", tripwire_triggered=False ) tutor = Agent( name="Python Tutor", instructions="Guide students without giving full solutions.", output_guardrails=[check_no_solutions] )
pythonfrom dataclasses import dataclass from agents import Agent, Runner, function_tool, RunContextWrapper @dataclass class TutoringContext: student_id: str session_id: str topics_covered: list[str] difficulty_level: str = "beginner" @function_tool def log_topic(wrapper: RunContextWrapper[TutoringContext], topic: str) -> str: """Log a topic as covered in this session.""" wrapper.context.topics_covered.append(topic) return f"Logged: {topic}" tutor = Agent( name="Python Tutor", instructions="Teach Python, tracking topics covered.", tools=[log_topic] ) async def main(): ctx = TutoringContext( student_id="student-123", session_id="session-456", topics_covered=[] ) result = await Runner.run( tutor, "Teach me about loops", context=ctx ) print(f"Topics covered: {ctx.topics_covered}")
learnflow-agents/
├── agents/
│ ├── __init__.py
│ ├── triage.py # Routing agent
│ ├── concepts.py # Concepts specialist
│ ├── debug.py # Debug specialist
│ └── exercise.py # Exercise generator
├── tools/
│ ├── __init__.py
│ ├── code_runner.py # Execute Python safely
│ └── search.py # Search documentation
├── guardrails/
│ ├── __init__.py
│ ├── input.py # Input validation
│ └── output.py # Output validation
├── main.py # FastAPI integration
└── pyproject.tomlpythonfrom fastapi import FastAPI, HTTPException from pydantic import BaseModel from agents import Agent, Runner app = FastAPI() # Initialize agents triage = Agent( name="Triage", instructions="Route questions to specialists", handoffs=[concepts_agent, debug_agent] ) class Question(BaseModel): text: str session_id: str class Answer(BaseModel): response: str agent_used: str @app.post("/ask", response_model=Answer) async def ask_question(question: Question): try: result = await Runner.run(triage, question.text) return Answer( response=result.final_output, agent_used=result.last_agent.name ) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @app.post("/ask/stream") async def ask_stream(question: Question): from fastapi.responses import StreamingResponse async def generate(): result = Runner.run_streamed(triage, question.text) async for event in result.stream_events(): if hasattr(event, 'delta'): yield event.delta return StreamingResponse(generate(), media_type="text/plain")
Traces available at: https://platform.openai.com/traces
pythonfrom agents import Runner, RunConfig config = RunConfig( workflow_name="tutoring-session", trace_id="custom-trace-123" ) result = await Runner.run(agent, "Hello", run_config=config)
Run: python scripts/verify.py
configuring-dapr-pubsub - Agent-to-agent messagingscaffolding-fastapi-dapr - FastAPI backend integrationstreaming-llm-responses - Response streaming patternsbuilding-chat-interfaces - Frontend chat UI| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 92,699 | 93,259 | +1% | 1 | 1 | 0% | 3,726 | 5,415 | +45% | 0 | 0 | — |
case-02 | fail→pass | 55,221 | 30,496 | -45% | 1 | 1 | 0% | 3,013 | 5,157 | +71% | 0 | 0 | — |
case-03 | pass→pass | 29,489 | 8,327 | -72% | 1 | 1 | 0% | 1,090 | 3,952 | +263% | 0 | 0 | — |
case-04 | pass→pass | 26,383 | 17,474 | -34% | 1 | 1 | 0% | 1,307 | 4,027 | +208% | 0 | 0 | — |
case-05 | fail→pass | 15,970 | 10,121 | -37% | 1 | 1 | 0% | 1,760 | 4,141 | +135% | 0 | 0 | — |
case-06 | fail→pass | 12,586 | 26,032 | +107% | 1 | 1 | 0% | 2,122 | 4,685 | +121% | 0 | 0 | — |
case-15 | pass→pass | 13,220 | 4,829 | -63% | 1 | 1 | 0% | 1,014 | 4,255 | +320% | 0 | 0 | — |
case-07 | fail→pass | 19,972 | 8,282 | -59% | 1 | 1 | 0% | 2,551 | 3,839 | +50% | 0 | 0 | — |
case-08 | pass→pass | 21,420 | 9,749 | -54% | 1 | 1 | 0% | 2,057 | 5,142 | +150% | 0 | 0 | — |
case-09 | pass→pass | 6,734 | 6,523 | -3% | 1 | 1 | 0% | 955 | 3,698 | +287% | 0 | 0 | — |
case-10 | fail→pass | 23,023 | 7,954 | -65% | 1 | 1 | 0% | 3,186 | 3,758 | +18% | 0 | 0 | — |
case-11 | pass→pass | 14,605 | 10,012 | -31% | 1 | 1 | 0% | 1,574 | 3,983 | +153% | 0 | 0 | — |
case-12 | fail→pass | 31,177 | 9,358 | -70% | 1 | 1 | 0% | 3,033 | 3,942 | +30% | 0 | 0 | — |
case-13 | fail→pass | 22,293 | 11,723 | -47% | 1 | 1 | 0% | 2,024 | 4,089 | +102% | 0 | 0 | — |
case-14 | pass→pass | 21,421 | 19,604 | -8% | 1 | 1 | 0% | 1,974 | 4,696 | +138% | 0 | 0 | — |
case-16 | fail→pass | 19,197 | 6,120 | -68% | 1 | 1 | 0% | 2,036 | 4,426 | +117% | 0 | 0 | — |
case-17 | pass→pass | 12,938 | 9,435 | -27% | 1 | 1 | 0% | 2,368 | 4,980 | +110% | 0 | 0 | — |
case-18 | fail→pass | 13,556 | 11,753 | -13% | 1 | 1 | 0% | 1,624 | 4,241 | +161% | 0 | 0 | — |
case-19 | fail→pass | 21,847 | 5,554 | -75% | 1 | 1 | 0% | 1,631 | 4,249 | +161% | 0 | 0 | — |
case-20 | pass→pass | 21,870 | 17,701 | -19% | 1 | 1 | 0% | 2,401 | 5,400 | +125% | 0 | 0 | — |
case-21 | pass→pass | 18,751 | 17,640 | -6% | 1 | 1 | 0% | 3,381 | 6,422 | +90% | 0 | 0 | — |
case-22 | pass→pass | 14,298 | 11,754 | -18% | 1 | 1 | 0% | 2,735 | 5,860 | +114% | 0 | 0 | — |
case-23 | pass→pass | 22,053 | 5,429 | -75% | 1 | 1 | 0% | 1,193 | 3,526 | +196% | 0 | 0 | — |
case-24 | pass→pass | 18,554 | 13,626 | -27% | 1 | 1 | 0% | 3,500 | 6,027 | +72% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of +46 percentage points is the difference between those two pass rates over the 24 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.