AgentStack
SKILL verified MIT Self-run

Openai Api

skill-noah-sheldon-ai-dev-kit-openai-api · by noah-sheldon

OpenAI API production patterns — Completions, Embeddings, function calling, fine-tuning, Batch API, streaming, Assistants API, cost optimization, error handling, safety, evaluation, and production architecture.

No reviews yet
0 installs
18 views
0.0% view→install

Install

$ agentstack add skill-noah-sheldon-ai-dev-kit-openai-api

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Openai Api? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

OpenAI API

Comprehensive guide to using the OpenAI API in production: Completions with structured outputs, Embeddings, function calling, fine-tuning, Batch API, streaming, Assistants API, cost optimization, error handling with retries, safety guardrails, and production architecture patterns.

When to Use

  • Building applications that call LLMs for chat completion, text generation, or structured data extraction
  • Generating and using embeddings for semantic search, clustering, or similarity matching
  • Integrating function/tool calling for LLM-powered agent workflows
  • Fine-tuning models for domain-specific tasks with higher accuracy
  • Processing large document batches asynchronously with the Batch API
  • Building conversational agents with the Assistants API (threads, code interpreter, file search)
  • Optimizing API costs, handling rate limits, and implementing production-grade error handling
  • Adding safety guardrails with moderation and output validation

Core Concepts

1. Completions API

Chat Completions with System Prompts:

from openai import OpenAI
import os

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

def chat_completion(messages: list[dict], model: str = "gpt-4o-mini") -> str:
    """Generate a chat completion with proper error handling."""
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0.3,
        max_tokens=1024,
        top_p=0.95,
        frequency_penalty=0.0,
        presence_penalty=0.0,
    )
    return response.choices[0].message.content

Structured Outputs via JSON Mode:

import json
from pydantic import BaseModel, Field
from typing import Literal

class ExtractionResult(BaseModel):
    """Structured extraction from unstructured text."""
    entities: list[dict[str, str]] = Field(description="Named entities found")
    sentiment: Literal["positive", "negative", "neutral"] = Field(description="Overall sentiment")
    summary: str = Field(description="One-sentence summary")
    confidence: float = Field(ge=0.0, le=1.0, description="Confidence in extraction")

def extract_structured(text: str) -> ExtractionResult:
    """Extract structured data using JSON mode with schema enforcement."""
    schema = ExtractionResult.model_json_schema()

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "Extract structured data from the text. Return valid JSON only."},
            {"role": "user", "content": text},
        ],
        response_format={"type": "json_schema", "json_schema": {"name": "extraction", "schema": schema}},
        temperature=0.0,  # Deterministic for extraction
    )

    result = json.loads(response.choices[0].message.content)
    return ExtractionResult(**result)

Tool Use / Function Calling:

tools = [
    {
        "type": "function",
        "function": {
            "name": "search_knowledge_base",
            "description": "Search the internal knowledge base for relevant documents",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {"type": "string", "description": "Search query"},
                    "top_k": {"type": "integer", "description": "Number of results", "default": 5},
                    "category": {"type": "string", "enum": ["engineering", "support", "sales"]},
                },
                "required": ["query"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "get_user_profile",
            "description": "Retrieve user profile by ID",
            "parameters": {
                "type": "object",
                "properties": {
                    "user_id": {"type": "string", "description": "User ID"},
                },
                "required": ["user_id"],
            },
        },
    },
]

def chat_with_tools(user_message: str) -> str:
    """Chat with tool calling — LLM decides which tools to call."""
    messages = [{"role": "user", "content": user_message}]

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )

    assistant_msg = response.choices[0].message

    # Execute tool calls
    if assistant_msg.tool_calls:
        messages.append(assistant_msg)

        for tool_call in assistant_msg.tool_calls:
            fn_name = tool_call.function.name
            args = json.loads(tool_call.function.arguments)

            if fn_name == "search_knowledge_base":
                result = search_knowledge_base(args["query"], args.get("top_k", 5))
            elif fn_name == "get_user_profile":
                result = get_user_profile(args["user_id"])
            else:
                result = {"error": f"Unknown function: {fn_name}"}

            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result),
            })

        # Get final response with tool results
        response = client.chat.completions.create(model="gpt-4o", messages=messages)

    return response.choices[0].message.content

Parallel Function Calling — multiple tools in a single turn:

# LLM can call multiple tools simultaneously
# The response will contain multiple tool_calls in assistant_msg.tool_calls
# Execute all tool calls in parallel for better latency

import asyncio

async def execute_tool_calls_parallel(tool_calls):
    """Execute multiple tool calls concurrently."""
    async def execute_one(tc):
        args = json.loads(tc.function.arguments)
        result = await TOOL_FUNCTIONS[tc.function.name](**args)
        return {"role": "tool", "tool_call_id": tc.id, "content": json.dumps(result)}

    return await asyncio.gather(*(execute_one(tc) for tc in tool_calls))

2. Embeddings API

def generate_embeddings(texts: list[str], model: str = "text-embedding-3-small") -> list[list[float]]:
    """Generate embeddings for a batch of texts."""
    response = client.embeddings.create(
        input=texts,
        model=model,
        dimensions=1536,  # Optional: reduce dimensions for cost savings
        encoding_format="float",
    )
    return [e.embedding for e in response.data]

def cosine_similarity(a: list[float], b: list[float]) -> float:
    """Compute cosine similarity between two embedding vectors."""
    import numpy as np
    a_np = np.array(a)
    b_np = np.array(b)
    return float(np.dot(a_np, b_np) / (np.linalg.norm(a_np) * np.linalg.norm(b_np)))

# Clustering with embeddings
from sklearn.cluster import KMeans

def cluster_documents(texts: list[str], n_clusters: int = 5) -> dict:
    """Cluster documents by embedding similarity."""
    embeddings = generate_embeddings(texts)
    kmeans = KMeans(n_clusters=n_clusters, random_state=42)
    labels = kmeans.fit_predict(embeddings)

    clusters = {}
    for i, label in enumerate(labels):
        clusters.setdefault(int(label), []).append(texts[i])
    return clusters

3. Fine-Tuning

Dataset Preparation:

// training.jsonl — one JSON object per line
{"messages": [{"role": "system", "content": "You are a helpful legal assistant."}, {"role": "user", "content": "What is the statute of limitations for breach of contract in California?"}, {"role": "assistant", "content": "In California, the statute of limitations for written contracts is 4 years from the date of breach (CCP § 337). For oral contracts, it is 2 years (CCP § 339)."}]}
{"messages": [{"role": "system", "content": "You are a helpful legal assistant."}, {"role": "user", "content": "Can I sue for emotional distress in a wrongful termination case?"}, {"role": "assistant", "content": "Yes, emotional distress damages may be available in wrongful termination claims, particularly under FEHA. However, the availability depends on the specific circumstances and legal theory pursued."}]}

Training Pipeline:

# Step 1: Validate dataset
import tiktoken

enc = tiktoken.get_encoding("cl100k_base")
total_tokens = 0
with open("training.jsonl") as f:
    for line in f:
        messages = json.loads(line)["messages"]
        tokens = sum(len(enc.encode(m["content"])) for m in messages)
        total_tokens += tokens

print(f"Total tokens: {total_tokens}, Estimated cost: ${total_tokens / 1000 * 0.008:.2f}")

# Step 2: Upload and start training
with open("training.jsonl", "rb") as f:
    file_resp = client.files.create(file=f, purpose="fine-tune")

job = client.fine_tuning.jobs.create(
    training_file=file_resp.id,
    model="gpt-4o-mini-2024-07-18",
    suffix="legal-assistant-v1",
    hyperparameters={"n_epochs": 3, "learning_rate_multiplier": 0.1},
)

# Step 3: Monitor training
while True:
    job = client.fine_tuning.jobs.retrieve(job.id)
    print(f"Status: {job.status}")
    if job.status in ["succeeded", "failed"]:
        break
    time.sleep(30)

fine_tuned_model = job.fine_tuned_model

4. Batch API

# Async batch processing — cheaper, slower
import json

def submit_batch_request(requests: list[dict], output_file: str = "batch_results.jsonl"):
    """Submit a batch of API requests for async processing."""
    # Write requests to JSONL
    batch_input_path = "batch_input.jsonl"
    with open(batch_input_path, "w") as f:
        for i, req in enumerate(requests):
            f.write(json.dumps({
                "custom_id": f"req-{i}",
                "method": "POST",
                "url": "/v1/chat/completions",
                "body": req,
            }) + "\n")

    # Upload file
    with open(batch_input_path, "rb") as f:
        batch_file = client.files.create(file=f, purpose="batch")

    # Create batch job
    batch_job = client.batches.create(
        input_file_id=batch_file.id,
        endpoint="/v1/chat/completions",
        completion_window="24h",
    )

    print(f"Batch job created: {batch_job.id}")
    return batch_job.id

def retrieve_batch_results(batch_id: str):
    """Retrieve completed batch results."""
    job = client.batches.retrieve(batch_id)
    if job.status != "completed":
        raise ValueError(f"Batch not completed: {job.status}")

    results_file = client.files.retrieve_content(job.output_file_id)
    results = []
    for line in results_file.text.strip().split("\n"):
        results.append(json.loads(line))
    return results

5. Streaming

def stream_completion(messages: list[dict], model: str = "gpt-4o"):
    """Stream tokens incrementally for responsive UX."""
    stream = client.chat.completions.create(
        model=model,
        messages=messages,
        stream=True,
        stream_options={"include_usage": True},
    )

    full_response = ""
    total_tokens = 0

    for chunk in stream:
        # Accumulate content
        if chunk.choices and chunk.choices[0].delta.content:
            content = chunk.choices[0].delta.content
            full_response += content
            yield content  # Yield to caller (e.g., SSE response)

        # Track token usage (only in final chunk)
        if chunk.usage:
            total_tokens = chunk.usage.total_tokens

    return full_response, total_tokens

# FastAPI SSE endpoint
from fastapi.responses import StreamingResponse

@app.post("/v1/chat/stream")
async def stream_chat(request: ChatRequest):
    async def event_generator():
        messages = [{"role": "user", "content": request.query}]
        for token in stream_completion(messages):
            yield f"data: {json.dumps({'token': token})}\n\n"
        yield "data: [DONE]\n\n"

    return StreamingResponse(event_generator(), media_type="text/event-stream")

6. Assistants API

# Create an assistant with file search and code interpreter
assistant = client.beta.assistants.create(
    name="Research Assistant",
    model="gpt-4o",
    instructions="You are a research assistant. Use file search to find relevant information in the knowledge base.",
    tools=[
        {"type": "file_search"},
        {"type": "code_interpreter"},
    ],
)

# Create a thread
thread = client.beta.threads.create()

# Add a message
client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="Analyze the sales data from Q3 and summarize the key trends.",
)

# Run the assistant
run = client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant.id,
)

# Poll for completion
while run.status != "completed":
    run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
    time.sleep(1)

# Get response messages
messages = client.beta.threads.messages.list(thread_id=thread.id)
for msg in messages.data:
    print(f"{msg.role}: {msg.content[0].text.value}")

7. Cost Optimization

| Strategy | Savings | Example | |----------|---------|---------| | Model selection | 10-100x | Use gpt-4o-mini for simple tasks, gpt-4o for complex reasoning | | Prompt compression | 20-40% | Remove redundant context, use concise instructions | | Semantic caching | 10-30% | Cache responses for similar queries (see mlops-rag skill) | | Batch API | 50% | Async processing for non-urgent requests | | Dimensionality reduction | 30-50% | Use 256-dim embeddings instead of 1536 when acceptable | | Fine-tuning | 20-40% | Smaller model fine-tuned can match larger model performance |

def smart_model_selection(task: str, complexity: str) -> str:
    """Select model based on task complexity."""
    if complexity == "high":
        return "gpt-4o"
    elif complexity == "medium":
        return "gpt-4o-mini"
    else:
        return "gpt-4o-mini"  # Default: cheapest capable model

8. Error Handling

import time
from openai import (
    OpenAI,
    RateLimitError,
    APIConnectionError,
    APIStatusError,
    APITimeoutError,
)

class CircuitBreaker:
    """Circuit breaker for API calls — fail fast when downstream is unhealthy."""
    def __init__(self, failure_threshold=5, recovery_timeout=60):
        self.failure_threshold = failure_threshold
        self.recovery_timeout = recovery_timeout
        self.failure_count = 0
        self.last_failure_time = None
        self.state = "closed"  # closed, open, half-open

    def call(self, func, *args, **kwargs):
        if self.state == "open":
            if time.time() - self.last_failure_time > self.recovery_timeout:
                self.state = "half-open"
            else:
                raise RuntimeError("Circuit breaker is open")

        try:
            result = func(*args, **kwargs)
            if self.state == "half-open":
                self.state = "closed"
            self.failure_count = 0
            return result
        except Exception:
            self.failure_count += 1
            self.last_failure_time = time.time()
            if self.failure_count >= self.failure_threshold:
                self.state = "open"
            raise

client = OpenAI()
circuit_breaker = CircuitBreaker(failure_threshold=5, recovery_timeout=60)

def call_openai_with_retry(messages: list[dict], model: str, max_retries: int = 5) -> str:
    """Call OpenAI with exponential backoff, fallback models, and circuit breaker."""
    models_to_try = [model, "gpt-4o-mini", "gpt-3.5-turbo"]
    base_delay = 1.0

    for attempt in range(max_retries):
        for model_choice in models_to_try:
            try:
                return circuit_breaker.call(
                    client.chat.completions.create,
                    model=model_choice,
                    messages=messages,
                    timeout=30.0,
                ).choices[0].message.content
            except RateLimitError:
                delay = base_delay * (2 ** attempt) + (hash(str(time.time())) % 1)  # jitter
                time.sleep(delay)
                continue

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [noah-sheldon](https://github.com/noah-sheldon)
- **Source:** [noah-sheldon/ai-dev-kit](https://github.com/noah-sheldon/ai-dev-kit)
- **License:** MIT
- **Homepage:** https://noahsheldon.dev

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.