GenAIHub
← Back to Technical Section

OpenAI Assistants API

Build Purpose-Built AI Assistants with Built-in Tools

Heads Up: Migration Coming

OpenAI has announced the Assistants API will be deprecated in favor of a new Agents platform by H1 2026. V1 was deprecated in Dec 2024. Current version is V2.

What is the Assistants API?

The OpenAI Assistants API lets you build purpose-built AI assistants with persistent threads, automatic context management, and powerful built-in tools like Code Interpreter, File Search, and Function Calling. It handles the complexity of conversation state, file processing, and tool orchestration so you can focus on your application logic.

"The Assistants API allows you to build AI assistants within your own applications. An Assistant has instructions and can leverage models, tools, and files to respond to user queries."

Code Interpreter

Run Python code

File Search

RAG built-in

Function Calling

Custom actions

Threads

Managed context

Core Concepts

Assistant

A configured AI entity with a name, instructions (system prompt), model selection, and enabled tools. Assistants are persistent and reusable across conversations.

Thread

A conversation session that maintains message history. OpenAI handles context window management, truncating older messages when needed. Threads persist across runs.

Message

User or assistant messages within a thread. Messages can include text, images, and file attachments. The API supports multimodal inputs with vision-capable models.

Run

An invocation of an Assistant on a Thread. The Run processes messages, executes tools, and generates responses. Runs can be polled or streamed.

Built-in Tools

Code Interpreter

  • • Writes & executes Python
  • • Sandboxed environment
  • • Data analysis & charts
  • • File generation (CSV, images)
  • • Iterative problem solving

File Search

  • • Built-in RAG system
  • • Up to 10,000 files
  • • Vector stores managed
  • • Keyword + semantic search
  • • Auto chunking & embedding

Function Calling

  • • Your custom functions
  • • External API integration
  • • Parallel function calls
  • • Structured outputs (JSON)
  • • Database queries, etc.

Quick Start: Create an Assistant

Create a simple math tutor assistant:

# pip install openai
from openai import OpenAI

client = OpenAI()

# 1. Create an Assistant
assistant = client.beta.assistants.create(
    name="Math Tutor",
    instructions="You are a math tutor. Help students with math problems step by step.",
    model="gpt-4o",
    tools=[{"type": "code_interpreter"}]
)

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

# 3. Add a Message
message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="Solve x² - 5x + 6 = 0"
)

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

# 5. Get the Response
if run.status == "completed":
    messages = client.beta.threads.messages.list(thread_id=thread.id)
    for msg in messages.data:
        if msg.role == "assistant":
            print(msg.content[0].text.value)

Expected Output

"To solve x² - 5x + 6 = 0, I'll factor the quadratic:

(x - 2)(x - 3) = 0

Setting each factor to zero:
x - 2 = 0  →  x = 2
x - 3 = 0  →  x = 3

The solutions are x = 2 and x = 3."

Example: File Search (RAG)

Upload files and let the assistant search through them:

from openai import OpenAI

client = OpenAI()

# Create a Vector Store
vector_store = client.beta.vector_stores.create(
    name="Company Docs"
)

# Upload files to it
file = client.files.create(
    file=open("employee_handbook.pdf", "rb"),
    purpose="assistants"
)

client.beta.vector_stores.files.create(
    vector_store_id=vector_store.id,
    file_id=file.id
)

# Create Assistant with File Search
assistant = client.beta.assistants.create(
    name="HR Assistant",
    instructions="Answer employee questions based on company documents.",
    model="gpt-4o",
    tools=[{"type": "file_search"}],
    tool_resources={
        "file_search": {
            "vector_store_ids": [vector_store.id]
        }
    }
)

# Now ask questions about your docs!
thread = client.beta.threads.create()
client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="What is the vacation policy?"
)

run = client.beta.threads.runs.create_and_poll(
    thread_id=thread.id,
    assistant_id=assistant.id
)

V2 Update: File Search now supports up to 10,000 files with automatic chunking, embedding, and hybrid (keyword + semantic) search. No need to manage vector stores yourself!

Example: Function Calling

Let your assistant call external APIs or custom functions:

import json
from openai import OpenAI

client = OpenAI()

# Define your functions
tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "City name"}
            },
            "required": ["city"]
        }
    }
}]

# Create assistant with function
assistant = client.beta.assistants.create(
    name="Weather Bot",
    instructions="Help users get weather information.",
    model="gpt-4o",
    tools=tools
)

# ... create thread, add message, create run ...

# Handle function call
if run.status == "requires_action":
    tool_calls = run.required_action.submit_tool_outputs.tool_calls
    
    tool_outputs = []
    for call in tool_calls:
        if call.function.name == "get_weather":
            args = json.loads(call.function.arguments)
            # Call your actual weather API here
            result = {"temp": "22°C", "condition": "Sunny"}
            tool_outputs.append({
                "tool_call_id": call.id,
                "output": json.dumps(result)
            })
    
    # Submit results back
    run = client.beta.threads.runs.submit_tool_outputs_and_poll(
        thread_id=thread.id,
        run_id=run.id,
        tool_outputs=tool_outputs
    )

Streaming Responses

Stream responses for a better user experience:

from openai import OpenAI

client = OpenAI()

# Stream the run
with client.beta.threads.runs.stream(
    thread_id=thread.id,
    assistant_id=assistant.id
) as stream:
    for text in stream.text_deltas:
        print(text, end="", flush=True)

# Or use event handlers for more control
from openai import AssistantEventHandler

class MyHandler(AssistantEventHandler):
    def on_text_delta(self, delta, snapshot):
        print(delta.value, end="", flush=True)
    
    def on_tool_call_created(self, tool_call):
        print(f"\n[Using {tool_call.type}...]")

with client.beta.threads.runs.stream(
    thread_id=thread.id,
    assistant_id=assistant.id,
    event_handler=MyHandler()
) as stream:
    stream.until_done()

API Architecture

Assistant

Config + Tools

Thread

Conversation

Messages

User + Assistant

Run

Execution

Assistants API vs Chat Completions

Aspect Assistants API Chat Completions
State Management Automatic (Threads) Manual (you store history)
Code Execution Built-in Interpreter Not available
File Search / RAG Built-in Vector Store DIY with embeddings
Pricing Higher (tools have cost) Lower (tokens only)
Best For Complex assistants Simple chat, full control

Pricing Considerations

Code Interpreter

$0.03

per session (up to 1hr)

File Search

$0.10

per GB/day (vector storage)

Thread Storage

Free

1st GB, then $0.20/GB/day

* Plus standard model token pricing. Prices as of Dec 2024. Check OpenAI docs for current rates.

Resources & References

Related Topics