
Ai
Wire up Python agents with the Vercel `ai` SDK—models, streaming events, tools, MCP, and structured outputs—for backend features in a solo project.
Install
npx skills add https://github.com/vercel-labs/ai-python --skill aiWhat is this skill?
- Install with `uv add ai` plus optional `ai[openai]` or `ai[anthropic]` extras
- Gateway and direct provider model selection via `ai.get_model`
- Async streaming with `agent.run` and `TextDelta` event handling
- Tool registration with `@ai.tool` for agent-callable functions
- Documents streams, structured output, MCP, and AI SDK UI surfaces in one skill
Adoption & trust: 6 installs on skills.sh; 70 GitHub stars.
Recommended Skills
Microsoft Foundrymicrosoft/azure-skills
Azure Aimicrosoft/azure-skills
Azure Hosted Copilot Sdkmicrosoft/azure-skills
Lark Eventlarksuite/cli
Running Claude Code Via Litellm Copilotxixu-me/skills
Setup Matt Pocock Skillsmattpocock/skills
Journey fit
Primary fit
Build is where you implement LLM-backed services; this skill documents installation and runtime patterns for the Python SDK rather than distribution or ops. Agent-tooling is the right shelf because the quick start centers on `ai.agent`, tools, streams, and provider configuration—not generic CRUD APIs alone.
SKILL.md
READMESKILL.md - Ai
# ai Use this skill when working with the Python `ai` SDK. ```bash uv add ai ``` Direct OpenAI-compatible and Anthropic-compatible providers require optional extras: `uv add "ai[openai]"` or `uv add "ai[anthropic]"`. AI Gateway works with the base package. ```python import ai ``` ## Quick start ```python import asyncio import ai @ai.tool async def get_weather(city: str) -> str: """Get current weather for a city.""" return f"Sunny, 72F in {city}" async def main() -> None: model = ai.get_model("gateway:anthropic/claude-sonnet-4") agent = ai.agent(tools=[get_weather]) messages = [ ai.system_message("You are a helpful weather assistant."), ai.user_message("What's the weather in Tokyo?"), ] 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) print(stream.output) if __name__ == "__main__": asyncio.run(main()) ``` `ai.stream(...)` and `agent.run(...)` are async context managers. Iterate events inside the context. After iteration, read final state from the stream object. ## Models and providers ```python model = ai.get_model() # reads AI_SDK_DEFAULT_MODEL model = ai.get_model("anthropic/claude-sonnet-4") # unprefixed: gateway route model = ai.get_model("gateway:anthropic/claude-sonnet-4") model = ai.get_model("openai:gpt-5.4") # direct provider route model = ai.get_model("anthropic:claude-sonnet-4-6") ``` - Gateway credentials use `AI_GATEWAY_API_KEY`. - Direct providers use provider-specific env vars such as `OPENAI_API_KEY` and `ANTHROPIC_API_KEY`. - Use `ai.get_provider(...)` when you need a custom base URL, API key, headers, or client. - Use `await ai.probe(model)` to check credentials and model availability. ```python provider = ai.get_provider( "openai", base_url="http://localhost:1234/v1", api_key="your_access_token_here", ) model = ai.Model("local-model", provider=provider) models = await ai.get_provider("anthropic").list_models() ``` Request-scoped provider options go through `params`: ```python params = { "providerOptions": { "gateway": {"sort": "cost"}, "anthropic": {"speed": "fast"}, } } async with ai.stream(model, messages, params=params) as stream: async for event in stream: ... ``` ## Messages and events Messages are Pydantic models with typed parts. Use builders for common roles and parts: ```python ai.system_message("Be concise.") ai.user_message("Describe this image:", ai.file_part(image_bytes, media_type="image/png")) ai.assistant_message(ai.thinking("scratchpad"), "Final answer") ai.tool_result_part("tc-1", result={"temp": 72}, tool_name="get_weather") ai.tool_message(tool_call_id="tc-1", result=72, tool_name="get_weather") ``` Common message properties: - `message.text`, `message.reasoning`. - `message.tool_calls`, `message.tool_results`. - `message.builtin_tool_calls`, `message.builtin_tool_returns`. - `message.files`, `message.images`, `message.videos`. - `message.get_output()` or `message.get_output(MyModel)`. Streams and agents yield event objects from `ai.events`: ```python async with ai.stream(model, messages, tools=tools) as stream: async for event in stream: if isinstance(event, ai.events.TextDelta): print(event.chunk, end="", flush=True) elif isinstance(event, ai.events.ToolEnd): print(event.tool_call.tool_name, event.tool_call.tool_args) elif isinstance(event, ai.events.ToolCallResult): for result in event.results: print(result.tool_name, result.result) elif isinstance(event, ai.events.HookEvent): print(event.hook.hook_id, event.hook.status) elif isinstance(event,