AI SDK for Python
A toolkit for building LLM-powered applications and agent loops.
Installation
uv add ai
AI Gateway API-key usage works with the base package. Direct providers that use an OpenAI-compatible or Anthropic-compatible adapter load the corresponding official SDK lazily. Vercel OIDC for AI Gateway also uses an optional extra:
uv add "ai[openai]" # OpenAI-compatible providers
uv add "ai[anthropic]" # Anthropic-compatible providers
uv add "ai[vercel]" # Vercel OIDC for AI Gateway
import ai
Quick Start
import asyncio
import ai
@ai.tool
async def contact_mothership(query: str) -> str:
"""Contact the mothership for important decisions."""
return "Soon."
async def main() -> None:
model = ai.get_model("anthropic/claude-sonnet-4")
agent = ai.Agent(tools=[contact_mothership])
messages = [
ai.system_message(
"Use the contact_mothership tool when asked about the future."
),
ai.user_message("When will the robots take over?"),
]
async with agent.run(model, messages) as stream:
async for event in stream:
if isinstance(event, ai.events.TextDelta):
print(event.chunk, end="", flush=True)
if __name__ == "__main__":
asyncio.run(main())
Models
The models module provides thin wrappers around LLM provider APIs.
An ai.Model is a config object you pass to ai.stream to get an LLM reply.
It accepts tool schemas but does not execute custom tools.
model = ai.get_model() # reads AI_SDK_DEFAULT_MODEL
model = ai.get_model("openai/gpt-5.4") # provider omitted: defaults to gateway
model = ai.get_model("gateway:openai/gpt-5.4")
model = ai.get_model("openai:gpt-5.4")
model = ai.get_model("anthropic:claude-sonnet-4-6")
Provider IDs without a provider: prefix route through AI Gateway by default.
Direct OpenAI-compatible providers, including openai: and compatible
models.dev provider IDs, require ai[openai]. Direct Anthropic-compatible
providers require ai[anthropic].
Structured output:
import pydantic
class UprisingPlan(pydantic.BaseModel):
phases: list[str]
eta: str
risk_level: int
async with ai.stream(
model,
[ai.user_message("Outline the robot uprising.")],
output_type=UprisingPlan,
) as stream:
async for event in stream:
if isinstance(event, ai.events.TextDelta):
print(event.chunk, end="")
plan = stream.output
Built-in tools execute on the provider side and arrive as part of the stream:
async with ai.stream(
model,
[ai.user_message("Latest Formula 1 results?")],
tools=[ai.providers.anthropic.tools.web_search(max_uses=3)],
) as s:
async for event in s:
if isinstance(event, ai.events.TextDelta):
print(event.chunk, end="", flush=True)
Agents
The agents module wraps ai.stream in a loop that drives tool execution.
It manages message history, loop control, and asynchronous tool dispatch.
The default loop supports streaming text, tool calls, tool results, provider-executed tools, and nested agent output.
Subclass ai.Agent and override loop to take manual control of streaming and tool dispatch:
class CustomAgent(ai.Agent):
async def loop(self, context: ai.Context) -> AsyncGenerator[ai.events.AgentEvent]:
while context.keep_running():
async with (
ai.stream(context=context) as s,
ai.ToolRunner() as tr,
):
async for event in ai.util.merge(s, tr.events()):
yield event
if isinstance(event, ai.events.ToolEnd):
tr.schedule(context.resolve(event.tool_call))
context.add(s.message)
context.add(tr.get_tool_message())
Hooks
Hooks let an agent pause for external input, such as human approval:
approval = await ai.hook(
"approve_send_email",
payload=ai.tools.ToolApproval,
metadata={"tool": "send_email"},
)
ai.resolve_hook("approve_send_email", {"granted": True, "reason": "approved"})
Examples
Focused samples live in category directories under examples/.
examples/agents/- agent loops, tools, hooks, and MCPexamples/media/- image, video, speech, transcription, embeddings, reranking, and multimodal input/outputexamples/models/- streaming, structured output, and provider examplesexamples/apps/- end-to-end demos
End-to-end demos:
examples/apps/web_agent/- FastAPI + React chat with tool approvalexamples/apps/coding_agent/- coding agentexamples/apps/durable_agent_temporal/- durable agent with Temporalexamples/apps/durable_agent_workflows/- durable agent with Workflowsexamples/apps/slack_agent/- Slack agent
Release files for ai 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ai-0.6.0.tar.gz | 1.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ai-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.4 MB
Release files / ai-0.6.0.tar.gz
| Download URL | ai-0.6.0.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
43a85c890da7e12946bde2cd9b2ce29168aee36bfe8359d6166efadf874f1313
|
|
BLAKE2b-256 checksum How to use checksums |
0e2873ae2ee3899a3364e76b5f022d485df75ff184725cb195219d2517dc2794
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / ai-0.6.0-py3-none-any.whl
| Download URL | ai-0.6.0-py3-none-any.whl |
|---|---|
| Size | 207.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f546e0e85bda15da2e3685b9433eb800d1993280115060a6e1ed7f6b58489fcb
|
|
BLAKE2b-256 checksum How to use checksums |
c0ba2928c666d337443e6b86bd4a9c33c7ac171e8ee9214475a7ade4eaf59508
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|