Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Almost any Python project can become an Actor, including projects for:
- **Web scraping and crawling** — The SDK is fully compatible with [Crawlee](https://crawlee.dev/python), which makes Apify a natural place to deploy and scale your crawlers (see the [Crawlee guide](https://docs.apify.com/sdk/python/docs/guides/crawlee)). It also works with other popular scraping libraries, such as [Scrapy](https://docs.apify.com/sdk/python/docs/guides/scrapy), [Scrapling](https://docs.apify.com/sdk/python/docs/guides/scrapling), or [Crawl4AI](https://docs.apify.com/sdk/python/docs/guides/crawl4ai).
- **Browser automation** — Drive a real browser with [Playwright](https://docs.apify.com/sdk/python/docs/guides/playwright) or [Selenium](https://docs.apify.com/sdk/python/docs/guides/selenium), or with higher-level tools such as [Browser Use](https://docs.apify.com/sdk/python/docs/guides/browser-use).
- **Web servers and APIs** — Run a [web server](https://docs.apify.com/sdk/python/docs/guides/running-webserver) inside an Actor to serve HTTP requests, for example to expose your scraper as a live API.
- **AI agents** — Host agents built with your framework of choice. Ready-made Actor templates cover [PydanticAI](https://apify.com/templates/python-pydanticai), [CrewAI](https://apify.com/templates/python-crewai), [LangGraph](https://apify.com/templates/python-langgraph), [LlamaIndex](https://apify.com/templates/python-llamaindex-agent), and [Smolagents](https://apify.com/templates/python-smolagents).
- **AI agents** — Host agents built with your framework of choice (see the [AI agents guide](https://docs.apify.com/sdk/python/docs/guides/ai-agents)). Ready-made Actor templates cover [PydanticAI](https://apify.com/templates/python-pydanticai), [CrewAI](https://apify.com/templates/python-crewai), [LangGraph](https://apify.com/templates/python-langgraph), [LlamaIndex](https://apify.com/templates/python-llamaindex-agent), and [Smolagents](https://apify.com/templates/python-smolagents).
- **MCP servers** — Deploy a Python MCP server as an Actor and make its tools available to any MCP client. See [MCP server](https://apify.com/templates/python-mcp-empty) and [MCP proxy](https://apify.com/templates/python-mcp-proxy) templates

Whatever you build, the Apify SDK doesn't lock you into a particular framework. Bring the libraries you already use, and let Apify run your project in the cloud.
Expand Down Expand Up @@ -199,7 +199,7 @@ The full SDK documentation lives at **[docs.apify.com/sdk/python](https://docs.a
| [Overview](https://docs.apify.com/sdk/python/docs/overview) | What the SDK is, what Actors are, and how the pieces fit together. |
| [Quick start](https://docs.apify.com/sdk/python/docs/quick-start) | Create, run, and deploy your first Python Actor. |
| [Concepts](https://docs.apify.com/sdk/python/docs/concepts/actor-lifecycle) | Actor lifecycle, input, storages, events, proxy management, interacting with other Actors, webhooks, accessing the Apify API, logging, configuration, and pay-per-event. |
| [Guides](https://docs.apify.com/sdk/python/docs/guides/beautifulsoup-httpx) | Integrations with BeautifulSoup, Parsel, Playwright, Selenium, Crawlee, Scrapy, Scrapling, Crawl4AI, and Browser Use, plus running a web server and using uv. |
| [Guides](https://docs.apify.com/sdk/python/docs/guides/beautifulsoup-httpx) | Integrations with BeautifulSoup, Parsel, Playwright, Selenium, Crawlee, Scrapy, Scrapling, Crawl4AI, and Browser Use, plus building AI agents, running a web server, and using uv. |
| [Upgrading](https://docs.apify.com/sdk/python/docs/upgrading/upgrading-to-v4) | Migrating between major versions. |
| [API reference](https://docs.apify.com/sdk/python/reference) | Generated reference for every class and method. |
| [Changelog](https://docs.apify.com/sdk/python/docs/changelog) | Release history and breaking changes. |
Expand Down
2 changes: 1 addition & 1 deletion docs/01_introduction/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Almost any Python project can become an Actor, including projects for:
- **Web scraping and crawling** - The SDK is fully compatible with [Crawlee](https://crawlee.dev/python), which makes Apify a natural place to deploy and scale your crawlers (see the [Crawlee guide](./guides/crawlee)). It also works with other popular scraping libraries, such as [Scrapy](./guides/scrapy), [Scrapling](./guides/scrapling), or [Crawl4AI](./guides/crawl4ai).
- **Browser automation** - Drive a real browser with [Playwright](./guides/playwright) or [Selenium](./guides/selenium), or with higher-level tools such as [Browser Use](./guides/browser-use).
- **Web servers and APIs** - Run a [web server](./guides/running-webserver) inside an Actor to serve HTTP requests, for example to expose your scraper as a live API.
- **AI agents** - Host agents built with your framework of choice. Ready-made Actor templates cover [PydanticAI](https://apify.com/templates/python-pydanticai), [CrewAI](https://apify.com/templates/python-crewai), [LangGraph](https://apify.com/templates/python-langgraph), [LlamaIndex](https://apify.com/templates/python-llamaindex-agent), and [Smolagents](https://apify.com/templates/python-smolagents).
- **AI agents** - Host agents built with your framework of choice (see the [AI agents guide](./guides/ai-agents)). Ready-made Actor templates cover [PydanticAI](https://apify.com/templates/python-pydanticai), [CrewAI](https://apify.com/templates/python-crewai), [LangGraph](https://apify.com/templates/python-langgraph), [LlamaIndex](https://apify.com/templates/python-llamaindex-agent), and [Smolagents](https://apify.com/templates/python-smolagents).
- **MCP servers** - Deploy a Python MCP server as an Actor and make its tools available to any MCP client. See the [MCP server](https://apify.com/templates/python-mcp-empty) and [MCP proxy](https://apify.com/templates/python-mcp-proxy) templates.

Whatever you build, the Apify SDK doesn't lock you into a particular framework. Bring the libraries you already use, and let Apify run your project in the cloud.
Expand Down
1 change: 1 addition & 0 deletions docs/01_introduction/quick-start.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ To see how you can integrate the Apify SDK with popular scraping libraries and f
- [Adaptive scraping with Scrapling](./guides/scrapling)
- [LLM-ready scraping with Crawl4AI](./guides/crawl4ai)
- [Browser AI agents with Browser Use](./guides/browser-use)
- [Building AI agents](./guides/ai-agents)

For other aspects of Actor development, explore these guides:

Expand Down
167 changes: 167 additions & 0 deletions docs/03_guides/13_ai_agents.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
---
id: ai-agents
title: Building AI agents
description: Host AI agents built with PydanticAI, CrewAI, LangGraph, LlamaIndex, or Smolagents as Apify Actors.
---

import RunnableCodeBlock from '@site/src/components/RunnableCodeBlock';

import PydanticaiExample from '!!raw-loader!roa-loader!./code/13_pydanticai.py';
import CrewaiExample from '!!raw-loader!roa-loader!./code/13_crewai.py';
import LanggraphExample from '!!raw-loader!roa-loader!./code/13_langgraph.py';
import LlamaindexExample from '!!raw-loader!roa-loader!./code/13_llamaindex.py';
import SmolagentsExample from '!!raw-loader!roa-loader!./code/13_smolagents.py';

In this guide, you'll learn how to host an AI agent as an Apify Actor, using the agent framework of your choice.

## Introduction

An AI agent is a program that uses a large language model (LLM) to decide what to do next. Instead of following a fixed script, it reasons about a task, calls tools to gather information or take actions, and loops until the task is done. The Python ecosystem offers several frameworks for building such agents, and the Apify SDK doesn't lock you into any of them.

Apify Actors are a natural home for agents:

- An agent is just a Python program, so wrapping it in `async with Actor:` is all it takes to run it on the platform.
- The platform scales runs, schedules them, and keeps logs, so you don't operate any infrastructure yourself.
- The [Apify Store](https://apify.com/store) gives your agent thousands of ready-made tools. Any Actor (a scraper, a browser automation, an API wrapper) can become a tool the agent calls.
- The [Apify OpenRouter proxy](https://apify.com/apify/openrouter) lets the agent talk to an LLM without managing a provider API key.
- Pay-per-event charging lets you monetize the agent and pass LLM costs on to its users.

## Choosing a framework

Apify maintains a ready-made Actor template for each of the popular agent frameworks. Each template is a complete, deployable Actor that you can use as a starting point. Pick the one that matches the framework you already use, or the style of agent you want to build:

| Framework | Good for | Template |
|---|---|---|
| [PydanticAI](#pydanticai) | Typed, Pydantic-native agents with tool calling | [`python-pydanticai`](https://apify.com/templates/python-pydanticai) |
| [CrewAI](#crewai) | Multi-agent "crews" that collaborate on a task | [`python-crewai`](https://apify.com/templates/python-crewai) |
| [LangGraph](#langgraph) | Graph-based agents with explicit state and control flow | [`python-langgraph`](https://apify.com/templates/python-langgraph) |
| [LlamaIndex](#llamaindex) | Retrieval-augmented agents over your own data | [`python-llamaindex-agent`](https://apify.com/templates/python-llamaindex-agent) |
| [Smolagents](#smolagents) | Lightweight code-writing agents from Hugging Face | [`python-smolagents`](https://apify.com/templates/python-smolagents) |

All of these templates live in the [actor-templates repository](https://github.com/apify/actor-templates), and you can scaffold any of them with the [Apify CLI](https://docs.apify.com/cli), for example `apify create my-agent --template python-pydanticai`.

## Connecting to an LLM

Every agent needs an LLM, and there are two ways to provide one.

The first is the [Apify OpenRouter proxy](https://apify.com/apify/openrouter), an OpenAI-compatible endpoint at `https://openrouter.apify.actor/api/v1` that fronts the full [OpenRouter](https://openrouter.ai) model catalog. The token usage is billed against the Apify account running the Actor, so no provider API key is required. The Actor authenticates with the proxy using the `APIFY_TOKEN` that the platform injects into every run. Any framework with an OpenAI-compatible client can point its base URL at the proxy, which is what most examples below do. To switch models, change the `model` input to any [OpenRouter model slug](https://openrouter.ai/models), for example `openai/gpt-4o-mini`.

The second is to call a provider such as OpenAI directly with your own API key, which the CrewAI example below does through LiteLLM. Keep the key out of the Actor input and source code. Read it from an environment variable, which on the platform you set as a [secret environment variable](https://docs.apify.com/platform/actors/development/programming-interface/environment-variables) and locally you export in your shell.

Each section below shows a complete, single-file Actor for one framework. They all read the input, run the agent, and store the result in the default dataset.

## PydanticAI

[PydanticAI](https://ai.pydantic.dev/) is an agent framework from the team behind Pydantic. It is strongly typed and integrates naturally with the [Pydantic models](./input-validation) the Apify SDK already uses. The following Actor runs an agent for a single prompt:

<RunnableCodeBlock className="language-python" language="python">
{PydanticaiExample}
</RunnableCodeBlock>

Set `output_type` to a Pydantic model instead of `str` to get a validated object back, which maps directly onto a dataset row.

## CrewAI

[CrewAI](https://www.crewai.com/) models a problem as a "crew" of role-playing agents that work through tasks. The following Actor defines a single analyst agent and one task:

<RunnableCodeBlock className="language-python" language="python">
{CrewaiExample}
</RunnableCodeBlock>

Note that:

- `kickoff_async` runs the crew without blocking the Actor's event loop.
- CrewAI calls the LLM through [LiteLLM](https://docs.litellm.ai/), so this example reads `OPENAI_API_KEY`. To route it through the Apify OpenRouter proxy instead, configure a custom `LLM` (see the [CrewAI LLM docs](https://docs.crewai.com/concepts/llms)).
- On a fresh container, crewAI shows a one-time trace-consent prompt. The template sets `CREWAI_TESTING=true` to suppress it; do the same in your Dockerfile.

## LangGraph

[LangGraph](https://www.langchain.com/langgraph) builds an agent as a graph with explicit state, which makes complex, multi-step control flow easy to follow. It builds on [LangChain](https://www.langchain.com/), so any LangChain chat model and tool works. The following Actor runs a single-turn agent:

<RunnableCodeBlock className="language-python" language="python">
{LanggraphExample}
</RunnableCodeBlock>

The example passes an empty `tools` list for brevity. Add LangChain tools to give the agent abilities, and read the final answer from the last message in the returned state.

## LlamaIndex

[LlamaIndex](https://www.llamaindex.ai/) is built for retrieval-augmented agents that reason over your own data. The following Actor runs a `ReActAgent` with a single tool:

<RunnableCodeBlock className="language-python" language="python">
{LlamaindexExample}
</RunnableCodeBlock>

Note that:

- `OpenAILike` is the LlamaIndex LLM class for OpenAI-compatible endpoints such as the Apify OpenRouter proxy. It needs the `llama-index-llms-openai-like` package.
- The agent decides on its own when to call the `word_count` tool. Add `FunctionTool`s of your own to extend it.

## Smolagents

[Smolagents](https://github.com/huggingface/smolagents) is a lightweight framework from Hugging Face whose agents write and run Python code to solve a task. The following Actor runs a `CodeAgent`:

<RunnableCodeBlock className="language-python" language="python">
{SmolagentsExample}
</RunnableCodeBlock>

A `CodeAgent` executes the Python code it generates, so run it in the isolated Actor container rather than on your own machine. Pass tools such as `WebSearchTool` in the `tools` list to let it gather information.

## Using Apify Actors as tools

An agent becomes useful once it can act on the world. On Apify, any of the thousands of Actors in the [Apify Store](https://apify.com/store) can become a tool: a scraper that fetches data, a browser automation that fills a form, or an API wrapper that posts a message.

For LangChain-based frameworks, such as LangGraph and CrewAI, the [`langchain-apify`](https://github.com/apify/langchain-apify) package exposes any Actor as a tool with a single line:

```python
from crewai_tools import ApifyActorsTool

# Let the agent scrape Instagram profiles by calling the apify/instagram-scraper Actor.
tools = [ApifyActorsTool('apify/instagram-scraper')]
```

For any other framework, call the Actor directly through the Actor's preconfigured API client and read its dataset:

```python
async def scrape_instagram(handle: str) -> list[dict]:
"""Scrape recent posts from an Instagram profile."""
run_input = {'directUrls': [f'https://www.instagram.com/{handle}/']}
run = await Actor.apify_client.actor('apify/instagram-scraper').call(run_input=run_input)
return (await Actor.apify_client.dataset(run['defaultDatasetId']).list_items()).items
```

For details on calling other Actors, see [Interacting with other Actors](../concepts/interacting-with-other-actors).

## Running on the Apify platform

Agents run on the standard [Apify Python base image](https://hub.docker.com/r/apify/actor-python), so no browser or extra system dependencies are needed. Add `apify` and your framework's packages to `requirements.txt`:

- PydanticAI: `pydantic-ai`
- CrewAI: `crewai` (or `crewai[tools]` for `ApifyActorsTool`)
- LangGraph: `langchain`, `langchain-openai`, `langgraph`
- LlamaIndex: `llama-index`, `llama-index-llms-openai-like`
- Smolagents: `smolagents[openai]`

To monetize the agent, use [pay-per-event charging](../concepts/pay-per-event). You define events such as `task-completed` in the Actor's monetization settings and trigger them from the code:

```python
await Actor.charge('task-completed')
```

This lets you charge users directly from the Actor and cover the cost of execution and LLM tokens. It pairs naturally with the Apify OpenRouter proxy, which already bills the LLM usage to the account running the Actor.

## Conclusion

In this guide, you learned how to host an AI agent as an Apify Actor. You can now build an agent with PydanticAI, CrewAI, LangGraph, LlamaIndex, or Smolagents, connect it to an LLM through the Apify OpenRouter proxy, give it Apify Actors as tools, and monetize it with pay-per-event. To get started, see the [Actor templates](https://apify.com/templates/categories/python). If you have questions or need assistance, feel free to reach out on our [GitHub](https://github.com/apify/apify-sdk-python) or join our [Discord community](https://discord.com/invite/jyEM2PRvMU). Happy building!

## Additional resources

- [Apify templates: PydanticAI](https://apify.com/templates/python-pydanticai)
- [Apify templates: CrewAI](https://apify.com/templates/python-crewai)
- [Apify templates: LangGraph](https://apify.com/templates/python-langgraph)
- [Apify templates: LlamaIndex](https://apify.com/templates/python-llamaindex-agent)
- [Apify templates: Smolagents](https://apify.com/templates/python-smolagents)
- [Apify: actor-templates repository](https://github.com/apify/actor-templates)
- [Apify: OpenRouter proxy](https://apify.com/apify/openrouter)
- [Apify: langchain-apify integration](https://github.com/apify/langchain-apify)
- [Apify blog: What are AI agents](https://blog.apify.com/what-are-ai-agents/)
34 changes: 34 additions & 0 deletions docs/03_guides/code/13_crewai.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import asyncio

from crewai import Agent, Crew, Task

from apify import Actor


async def main() -> None:
async with Actor:
actor_input = await Actor.get_input() or {}
topic = actor_input.get('topic', 'the Apify platform')
model = actor_input.get('model', 'gpt-4o-mini')

# CrewAI calls the LLM through LiteLLM, which reads OPENAI_API_KEY.
analyst = Agent(
role='Research Analyst',
goal=f'Write a short, accurate summary about {topic}.',
backstory='An analyst who turns a topic into a concise brief.',
llm=model,
)
task = Task(
description=f'Write a three-sentence summary about {topic}.',
expected_output='A three-sentence summary.',
agent=analyst,
)

# `kickoff_async` keeps the Actor's event loop responsive.
result = await Crew(agents=[analyst], tasks=[task]).kickoff_async()
Actor.log.info(f'Crew result:\n{result.raw}')
await Actor.push_data({'topic': topic, 'summary': result.raw})


if __name__ == '__main__':
asyncio.run(main())
33 changes: 33 additions & 0 deletions docs/03_guides/code/13_langgraph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import asyncio
import os

from langchain.agents import create_agent
from langchain_openai import ChatOpenAI

from apify import Actor

OPENROUTER_BASE_URL = 'https://openrouter.apify.actor/api/v1'


async def main() -> None:
async with Actor:
actor_input = await Actor.get_input() or {}
query = actor_input.get('query', 'What is an Apify Actor?')
model = actor_input.get('model', 'openai/gpt-4o-mini')

# Route the LLM through the Apify OpenRouter proxy (no provider key needed).
llm = ChatOpenAI(
model=model,
base_url=OPENROUTER_BASE_URL,
api_key=os.environ['APIFY_TOKEN'],
)
agent = create_agent(llm, tools=[])

result = await agent.ainvoke({'messages': [('user', query)]})
answer = result['messages'][-1].content
Actor.log.info(f'Agent answer:\n{answer}')
await Actor.push_data({'query': query, 'answer': answer})


if __name__ == '__main__':
asyncio.run(main())
Loading