← スキル一覧に戻る

scaffolding-openai-agents
by Razamirxa
⭐ 0🍴 0📅 2026年1月11日
SKILL.md
name: scaffolding-openai-agents description: Build AI agents with OpenAI's API. Use when creating tool-calling agents, multi-step reasoning systems, function calling implementations, or autonomous AI workflows. Triggers include "OpenAI agent", "function calling", "tool use", "agent loop", "autonomous agent", or "AI assistant with tools".
Scaffolding OpenAI Agents Skill
Build production-ready AI agents with OpenAI's function calling and tool use capabilities.
Agent Architecture
┌──────────────────────────────────────────────────────────┐
│ AGENT LOOP │
├──────────────────────────────────────────────────────────┤
│ 1. User Input → LLM │
│ 2. LLM decides: respond OR call tool(s) │
│ 3. If tool call → Execute tool → Return result to LLM │
│ 4. Repeat until LLM responds without tool calls │
│ 5. Return final response to user │
└──────────────────────────────────────────────────────────┘
Quick Start
Installation
pip install openai
Minimal Agent with Tools
import json
from openai import OpenAI
client = OpenAI()
# Define tools
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name, e.g., 'San Francisco'"
}
},
"required": ["location"]
}
}
}
]
# Tool implementation
def get_weather(location: str) -> str:
# In real app, call weather API
return f"Weather in {location}: 72°F, sunny"
# Map function names to implementations
tool_functions = {
"get_weather": get_weather
}
# Agent loop
def run_agent(user_message: str) -> str:
messages = [{"role": "user", "content": user_message}]
while True:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=tools
)
message = response.choices[0].message
# If no tool calls, return response
if not message.tool_calls:
return message.content
# Process tool calls
messages.append(message)
for tool_call in message.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
# Execute tool
result = tool_functions[func_name](**func_args)
# Add tool result to messages
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": str(result)
})
# Usage
print(run_agent("What's the weather in Tokyo?"))
Defining Tools
Basic Tool Schema
{
"type": "function",
"function": {
"name": "function_name",
"description": "Clear description of what this function does",
"parameters": {
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "What this parameter is for"
},
"param2": {
"type": "integer",
"description": "Another parameter"
}
},
"required": ["param1"]
}
}
}
Supported Parameter Types
# String
{"type": "string", "description": "A text value"}
# Number
{"type": "number", "description": "A decimal number"}
# Integer
{"type": "integer", "description": "A whole number"}
# Boolean
{"type": "boolean", "description": "True or false"}
# Array
{
"type": "array",
"items": {"type": "string"},
"description": "A list of strings"
}
# Enum
{
"type": "string",
"enum": ["option1", "option2", "option3"],
"description": "One of the allowed values"
}
# Object
{
"type": "object",
"properties": {
"nested_field": {"type": "string"}
}
}
Real-World Tool Examples
tools = [
# Search tool
{
"type": "function",
"function": {
"name": "search_web",
"description": "Search the web for information. Use for current events or facts.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The search query"
},
"num_results": {
"type": "integer",
"description": "Number of results to return (1-10)",
"default": 5
}
},
"required": ["query"]
}
}
},
# Database query tool
{
"type": "function",
"function": {
"name": "query_database",
"description": "Execute a read-only SQL query on the database",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "SQL SELECT query to execute"
}
},
"required": ["query"]
}
}
},
# Send email tool
{
"type": "function",
"function": {
"name": "send_email",
"description": "Send an email to a recipient",
"parameters": {
"type": "object",
"properties": {
"to": {
"type": "string",
"description": "Recipient email address"
},
"subject": {
"type": "string",
"description": "Email subject line"
},
"body": {
"type": "string",
"description": "Email body content"
}
},
"required": ["to", "subject", "body"]
}
}
}
]
Agent Patterns
1. Simple ReAct Agent
class SimpleAgent:
def __init__(self, tools: list, tool_functions: dict):
self.client = OpenAI()
self.tools = tools
self.tool_functions = tool_functions
self.system_prompt = """You are a helpful assistant with access to tools.
Think step by step before acting. Use tools when needed."""
def run(self, user_input: str, max_turns: int = 10) -> str:
messages = [
{"role": "system", "content": self.system_prompt},
{"role": "user", "content": user_input}
]
for _ in range(max_turns):
response = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=self.tools
)
message = response.choices[0].message
if not message.tool_calls:
return message.content
messages.append(message)
for tool_call in message.tool_calls:
result = self._execute_tool(tool_call)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
return "Max turns reached without final response"
def _execute_tool(self, tool_call) -> str:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
if func_name not in self.tool_functions:
return f"Error: Unknown function {func_name}"
try:
result = self.tool_functions[func_name](**func_args)
return str(result)
except Exception as e:
return f"Error executing {func_name}: {str(e)}"
2. Conversational Agent with Memory
class ConversationalAgent:
def __init__(self, tools: list, tool_functions: dict):
self.client = OpenAI()
self.tools = tools
self.tool_functions = tool_functions
self.conversation_history = []
self.system_prompt = "You are a helpful assistant. Remember our conversation."
def chat(self, user_input: str) -> str:
self.conversation_history.append({"role": "user", "content": user_input})
messages = [
{"role": "system", "content": self.system_prompt},
*self.conversation_history
]
while True:
response = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=self.tools
)
message = response.choices[0].message
if not message.tool_calls:
self.conversation_history.append({
"role": "assistant",
"content": message.content
})
return message.content
messages.append(message)
for tool_call in message.tool_calls:
result = self._execute_tool(tool_call)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
def _execute_tool(self, tool_call) -> str:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
return str(self.tool_functions[func_name](**func_args))
def clear_history(self):
self.conversation_history = []
3. Planning Agent
class PlanningAgent:
"""Agent that creates a plan before executing."""
def __init__(self, tools: list, tool_functions: dict):
self.client = OpenAI()
self.tools = tools
self.tool_functions = tool_functions
def run(self, task: str) -> str:
# Step 1: Create plan
plan = self._create_plan(task)
print(f"Plan:\n{plan}\n")
# Step 2: Execute plan
return self._execute_plan(task, plan)
def _create_plan(self, task: str) -> str:
tool_descriptions = "\n".join(
f"- {t['function']['name']}: {t['function']['description']}"
for t in self.tools
)
response = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": f"""Create a step-by-step plan to accomplish the task.
Available tools:
{tool_descriptions}
Format each step as: Step N: [action]"""
},
{"role": "user", "content": task}
]
)
return response.choices[0].message.content
def _execute_plan(self, task: str, plan: str) -> str:
messages = [
{
"role": "system",
"content": f"Execute this plan step by step:\n{plan}\n\nUse tools as needed."
},
{"role": "user", "content": task}
]
while True:
response = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=self.tools
)
message = response.choices[0].message
if not message.tool_calls:
return message.content
messages.append(message)
for tool_call in message.tool_calls:
result = self._execute_tool(tool_call)
print(f"Tool: {tool_call.function.name} → {result[:100]}...")
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
def _execute_tool(self, tool_call) -> str:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
return str(self.tool_functions[func_name](**func_args))
Parallel Tool Calls
OpenAI can call multiple tools in parallel:
def process_parallel_tool_calls(message, tool_functions: dict) -> list:
"""Process multiple tool calls that came in a single response."""
results = []
for tool_call in message.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
result = tool_functions[func_name](**func_args)
results.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": str(result)
})
return results
Structured Outputs
Force specific response format:
from pydantic import BaseModel
class TaskResult(BaseModel):
success: bool
result: str
next_steps: list[str]
response = client.beta.chat.completions.parse(
model="gpt-4o-mini",
messages=[...],
response_format=TaskResult
)
result = response.choices[0].message.parsed
print(result.success, result.result)
Error Handling
def safe_tool_execution(tool_call, tool_functions: dict) -> str:
"""Execute tool with comprehensive error handling."""
func_name = tool_call.function.name
# Check if function exists
if func_name not in tool_functions:
return json.dumps({
"error": f"Unknown function: {func_name}",
"available_functions": list(tool_functions.keys())
})
# Parse arguments
try:
func_args = json.loads(tool_call.function.arguments)
except json.JSONDecodeError as e:
return json.dumps({
"error": f"Invalid JSON arguments: {str(e)}",
"raw_arguments": tool_call.function.arguments
})
# Execute function
try:
result = tool_functions[func_name](**func_args)
return json.dumps({"success": True, "result": result})
except TypeError as e:
return json.dumps({
"error": f"Invalid arguments for {func_name}: {str(e)}"
})
except Exception as e:
return json.dumps({
"error": f"Execution error: {str(e)}",
"function": func_name,
"arguments": func_args
})
Streaming Agent Responses
def run_agent_streaming(user_input: str, tools: list, tool_functions: dict):
"""Run agent with streaming output."""
messages = [{"role": "user", "content": user_input}]
while True:
stream = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=tools,
stream=True
)
collected_content = ""
collected_tool_calls = []
for chunk in stream:
delta = chunk.choices[0].delta
if delta.content:
print(delta.content, end="", flush=True)
collected_content += delta.content
if delta.tool_calls:
for tc in delta.tool_calls:
# Handle streaming tool calls
# (accumulate function name and arguments)
pass
if not collected_tool_calls:
print() # Newline after streaming
return collected_content
# Process tool calls
# ... (similar to non-streaming version)
Best Practices
- Clear tool descriptions - LLM needs to understand when to use each tool
- Validate tool inputs - Don't trust LLM-generated arguments blindly
- Handle errors gracefully - Return error messages, don't crash
- Set max iterations - Prevent infinite loops
- Log tool calls - For debugging and monitoring
- Use appropriate model - gpt-4o for complex reasoning, gpt-4o-mini for speed
- Test edge cases - What if tool fails? What if LLM hallucinates tool names?
Common Pitfalls
- Vague tool descriptions - LLM won't know when to use the tool
- No max iterations - Agent can loop forever
- Ignoring tool errors - Leads to poor responses
- Too many tools - Confuses the model, increases latency
- Missing required params - LLM might not provide all required arguments
References
- references/tool-design.md - Tool design patterns
- references/agent-patterns.md - Advanced agent architectures
- OpenAI Function Calling Docs
スコア
総合スコア
50/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です