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.7.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.7.0.tar.gz | 1.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ai-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.4 MB
Release files / ai-0.7.0.tar.gz
| Download URL | ai-0.7.0.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1b0b4b20430ab12de38e388b893b2774681f6a3b1ec79850f64db324b5ee55d1
|
|
BLAKE2b-256 checksum How to use checksums |
3c09efc7051a582507474e5f8c9333b1f6bcfd0f43736a014428c3d6f65e69d3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.16 {"installer":{"name":"uv","version":"0.12.16","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.7.0-py3-none-any.whl
| Download URL | ai-0.7.0-py3-none-any.whl |
|---|---|
| Size | 210.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9a94279254814e562cb65618aedd5c5f832e59816f5be25375913c737083365a
|
|
BLAKE2b-256 checksum How to use checksums |
ed427823fa36389f04c4d728d9ed58cdcf27fec4d93e54a722839015b1eeadf5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.16 {"installer":{"name":"uv","version":"0.12.16","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}
|