> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ziet.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agents

> Build autonomous agents that orchestrate multiple actions to complete complex tasks

## What are Agents?

**Agents** are intelligent orchestrators that coordinate multiple actions to complete complex tasks. Unlike traditional scripts, agents are **declarative** - you define what they should do through instructions, not imperative code.

```python theme={null}
from ziet import Agent, Action, memory

@Agent(
    id="support_agent",
    name="CustomerSupport",
    description="Handle customer inquiries",
    instructions="""
    You are a customer support agent. Your workflow:
    1. Fetch customer data using fetch_customer action
    2. Get their latest order using get_order action
    3. Check shipment status using track_shipment action
    4. Store all results in memory
    5. Provide a helpful response to the customer
    
    Always be polite and provide tracking numbers when available.
    """,
    actions=["fetch_customer", "get_order", "track_shipment"],
    model="gpt-4o-mini"
)
class CustomerSupportAgent:
    pass  # Agent behavior is defined by instructions and strategies
```

## Agent Parameters

Configure agent behavior with decorator parameters:

```python theme={null}
@Agent(
    id="search_agent",                    # Required: Unique identifier (use <verb>_agent)
    name="SearchAgent",                   # Required: Human-readable name
    description="Search and analyze",     # Optional: Description
    instructions="""...""",               # Required: Instructions for agent behavior
    actions=["action1", "action2"],       # Required: Available action IDs
    model="gpt-4o-mini",                  # Optional: LLM model
    max_steps=40                          # Optional: Max action calls per run
)
class MyAgent:
    pass  # Agent behavior is defined by instructions
```

### Parameter Details

<ParamField path="id" type="string" required>
  Unique identifier for the agent. Use `<verb>_agent` naming pattern.

  ```python theme={null}
  @Agent(
      id="booking_agent",
      name="FlightBooker",
      instructions="...",
      actions=["book_flight"]
  )
  class FlightBooker:
      pass

  # Deployed to: /agents/booking_agent/run
  # CLI: ziet run booking_agent
  ```
</ParamField>

<ParamField path="name" type="string" required>
  Human-readable name displayed in the dashboard and logs.

  ```python theme={null}
  @Agent(
      id="booking_agent",
      name="Flight Booking Agent",
      instructions="...",
      actions=["book_flight"]
  )
  class FlightBooker:
      pass
  ```
</ParamField>

<ParamField path="description" type="string" optional>
  Description of what the agent does. Shown in dashboard and API docs.

  ```python theme={null}
  @Agent(
      id="booking_agent",
      name="FlightBooker",
      description="Research airlines and book flights with approval",
      instructions="...",
      actions=["search_flights", "book_flight"]
  )
  class FlightBooker:
      pass
  ```
</ParamField>

<ParamField path="instructions" type="string" required>
  System prompt that defines agent behavior. This is how you tell the agent what to do, which actions to call, and how to handle scenarios. **This is the core of your agent** - think of it as the agent's job description.

  ```python theme={null}
  @Agent(
      id="booking_agent",
      name="FlightBooker",
      instructions="""
      You are a flight booking agent. Your workflow:
      1. Search for flights using search_flights action
      2. Compare prices and analyze options
      3. Store top 3 recommendations in memory with key 'top_flights'
      4. Book the selected flight using book_flight action
      5. Store booking confirmation in memory
      
      Always prioritize value over just cheapest price. Use memory to
      share data between steps.
      """,
      actions=["search_flights", "book_flight"]
  )
  class FlightBooker:
      pass
  ```
</ParamField>

<ParamField path="actions" type="list[string]" required>
  List of action IDs this agent can use. Agent can only call actions specified here.

  ```python theme={null}
  @Agent(
      id="research_agent",
      name="ResearchAgent",
      instructions="Research topics using available actions",
      actions=["search_google", "scrape_website", "summarize_text"]
  )
  class ResearchAgent:
      pass
  ```
</ParamField>

<ParamField path="model" type="string" default="gpt-4o-mini">
  LLM model to use for AI-powered agents. Supported models:

  * `gpt-4o-mini` (default, fast and cheap)
  * `gpt-4o` (most capable)
  * `gpt-4-turbo`
  * `claude-3-5-sonnet-20241022`
  * `claude-3-opus-20240229`

  ```python theme={null}
  @Agent(model="gpt-4o")  # Use GPT-4 for complex reasoning
  class ComplexAgent:
      ...
  ```
</ParamField>

<ParamField path="max_steps" type="int" default="40">
  Maximum number of actions the agent can call in a single run. Prevents infinite loops.

  ```python theme={null}
  @Agent(
      id="simple_agent",
      name="SimpleAgent",
      instructions="...",
      actions=["action1"],
      max_steps=20
  )
  class SimpleAgent:
      pass
  ```
</ParamField>

## Building Agents

### Minimal Agent

The simplest agent with just instructions:

```python theme={null}
from ziet import Agent

@Agent(
    id="greeting_agent",
    name="GreetingAgent",
    instructions="Greet the user warmly and wish them a great day!",
    actions=[],
    model="gpt-4o-mini"
)
class GreetingAgent:
    pass  # Agent behavior is fully defined by instructions
```

### Agent with Actions

An agent that uses actions to get work done:

```python theme={null}
from ziet import Agent, Action, memory
from ziet.integrations import google, openai

# Define actions
@Action(
    id="search_google",
    name="Search Google",
    description="Search Google for information"
)
def search_google(query: str) -> None:
    results = google.search(query, num_results=10)
    memory.add(key="search_results", value=results)

@Action(
    id="summarize_results",
    name="Summarize Results",
    description="Summarize search results using AI"
)
def summarize_results() -> None:
    results = memory.get("search_results")
    prompt = f"Summarize these search results: {results}"
    summary = openai.chat([{"role": "user", "content": prompt}])
    memory.add(key="final_summary", value=summary)

# Define agent
@Agent(
    id="research_agent",
    name="ResearchAgent",
    description="Research topics and provide summaries",
    instructions="""
    You are a research agent. Follow this workflow:
    1. Use search_google action to find information on the topic
    2. Store results in memory
    3. Use summarize_results action to create a concise summary
    4. All data should be stored in memory for retrieval
    
    Be thorough but concise. Focus on factual information.
    """,
    actions=["search_google", "summarize_results"],
    model="gpt-4o-mini",
    max_steps=20
)
class ResearchAgent:
    pass  # Agent orchestrates actions based on instructions
```

## Using Memory

Actions store data in memory, and your agent instructions can reference that data:

```python theme={null}
from ziet import Agent, Action, memory

@Action(
    id="fetch_user",
    name="Fetch User",
    description="Fetch user from database"
)
def fetch_user(user_id: str) -> None:
    user = database.get_user(user_id)
    memory.add(key="current_user", value=user)

@Agent(
    id="profile_agent",
    name="ProfileAgent",
    instructions="""
    1. Use fetch_user action to get user data
    2. User data will be stored in memory with key 'current_user'
    3. Analyze the user profile and provide insights
    4. Store your analysis in memory with key 'profile_analysis'
    """,
    actions=["fetch_user"]
)
class ProfileAgent:
    pass
```

[Learn more about Memory →](/core/memory)

## Using Integrations

Agents can use actions that leverage built-in integrations:

```python theme={null}
from ziet import Agent, Action, memory
from ziet.integrations import google, openai, stripe, sendgrid

@Action(
    id="search_flights",
    name="Search Flights",
    description="Search for flights using Google"
)
def search_flights(origin: str, dest: str) -> None:
    results = google.search(f"flights {origin} to {dest}")
    memory.add(key="flight_results", value=results)

@Action(
    id="analyze_flights",
    name="Analyze Flights",
    description="Analyze flight options with AI"
)
def analyze_flights() -> None:
    flights = memory.get("flight_results")
    prompt = f"Which flight offers best value? {flights}"
    analysis = openai.chat([{"role": "user", "content": prompt}])
    memory.add(key="flight_analysis", value=analysis)

@Agent(
    id="booking_agent",
    name="BookingAgent",
    instructions="""
    1. Search for flights using search_flights action
    2. Analyze options using analyze_flights action
    3. Present the best recommendation to the user
    """,
    actions=["search_flights", "analyze_flights"]
)
class BookingAgent:
    pass
```

[View all integrations →](/integrations/overview)

## Testing Agents

Test your agent locally before deploying:

```bash theme={null}
ziet run --local --agent research_agent
```

This runs your agent in local mode with test data. You'll see:

* Agent execution flow
* Actions being called
* Memory operations
* Integration calls (mocked locally)
* Strategy execution

Expected output:

```
🧪 Running agent locally: research_agent

[INFO] Starting local run...
[INFO] Agent research_agent initialized
[INFO] Calling action: search_google
[INFO] Memory added: key=search_results
[INFO] Calling action: summarize_results
[INFO] Memory added: key=final_summary
✅ Local run completed

Agent completed successfully
```

## Deployment

Deploy your agent:

```bash theme={null}
ziet deploy
```

After deployment, invoke via:

<Tabs>
  <Tab title="API">
    ```bash theme={null}
    curl -X POST https://api.ziet.ai/agents/research_agent/run \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"topic": "quantum computing"}'
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    ziet run research_agent --topic "quantum computing"
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    from ziet import Client

    client = Client(api_key="your_key")
    result = client.run_agent(
        agent_id="research_agent",
        data={"topic": "quantum computing"}
    )
    ```
  </Tab>

  <Tab title="Dashboard">
    1. Go to [dashboard.ziet.ai](https://dashboard.ziet.ai)
    2. Navigate to **Agents** → **research\_agent**
    3. Click **Run Agent**
    4. Fill in parameters
    5. Click **Execute**
  </Tab>
</Tabs>

## Best Practices

<AccordionGroup>
  <Accordion title="Keep agents focused" icon="bullseye">
    Each agent should have a clear, single purpose.

    ✅ **Good**: Separate agents for different workflows

    ```python theme={null}
    @Agent(
        id="booking_agent",
        name="FlightBooker",
        instructions="Book flights after research and approval",
        actions=["book_flight", "charge_payment"]
    )
    class FlightBooker:
        pass

    @Agent(
        id="hotel_agent",
        name="HotelBooker",
        instructions="Find and book hotels",
        actions=["search_hotels", "book_hotel"]
    )
    class HotelBooker:
        pass
    ```

    ❌ **Bad**: One agent doing everything

    ```python theme={null}
    @Agent(
        id="travel_agent",
        instructions="Books flights, hotels, cars, restaurants...",
        actions=["book_everything"]  # Too broad!
    )
    class TravelAgent:
        pass
    ```
  </Accordion>

  <Accordion title="Use descriptive IDs" icon="tag">
    Agent IDs should follow `<verb>_agent` pattern and be clear.

    ✅ **Good**

    * `support_agent`
    * `research_agent`
    * `booking_agent`

    ❌ **Bad**

    * `agent1`
    * `my-agent`
    * `test`
  </Accordion>

  <Accordion title="Write clear instructions" icon="book">
    Your instructions are the core of your agent - make them detailed and specific.

    ```python theme={null}
    @Agent(
        id="research_agent",
        name="ResearchAgent",
        instructions="""
        You are a research agent. Follow this workflow:
        1. Use search_google action to find information on the topic
        2. Store results in memory with key 'search_results'
        3. Use summarize_text action to create a concise summary
        4. Store summary in memory with key 'final_summary'
        
        Expected input:
        - topic (string, required): Topic to research
        - depth (string, optional): "shallow" or "deep"
        
        Be thorough but concise. Focus on factual information.
        Always store intermediate results in memory for debugging.
        """,
        actions=["search_google", "summarize_text"]
    )
    class ResearchAgent:
        pass
    ```
  </Accordion>

  <Accordion title="Set appropriate max_steps" icon="chart-simple">
    Prevent runaway execution by setting reasonable limits.

    ```python theme={null}
    # Simple agents
    @Agent(
        id="greeting_agent",
        name="GreetingAgent",
        instructions="Greet the user",
        actions=[],
        max_steps=5
    )
    class GreetingAgent:
        pass

    # Complex agents
    @Agent(
        id="research_agent",
        name="ResearchAgent",
        instructions="...",
        actions=["search", "scrape", "summarize"],
        max_steps=50  # May need many searches and retries
    )
    class ResearchAgent:
        pass
    ```
  </Accordion>

  <Accordion title="Guide memory usage in instructions" icon="database">
    Tell your agent how to use memory in the instructions.

    ```python theme={null}
    @Agent(
        id="analysis_agent",
        name="AnalysisAgent",
        instructions="""
        Workflow:
        1. Fetch data using fetch_data action
        2. Data will be stored in memory with key 'raw_data'
        3. Analyze the data and identify key insights
        4. Store your analysis in memory with key 'analysis_result'
        5. Store top 3 recommendations in memory with key 'recommendations'
        
        Use memory to share data between actions and preserve context.
        """,
        actions=["fetch_data"]
    )
    class AnalysisAgent:
        pass
    ```
  </Accordion>

  <Accordion title="Specify available actions clearly" icon="bolt">
    Only list actions the agent actually needs.

    ```python theme={null}
    # Good: Specific actions for the task
    @Agent(
        id="booking_agent",
        name="BookingAgent",
        instructions="...",
        actions=["search_flights", "compare_prices", "book_flight"]
    )
    class BookingAgent:
        pass

    # Bad: Too many irrelevant actions
    @Agent(
        id="booking_agent",
        name="BookingAgent",
        instructions="...",
        actions=["search_flights", "book_hotel", "rent_car", "book_restaurant"]
    )
    class BookingAgent:
        pass
    ```
  </Accordion>
</AccordionGroup>

## Limitations

<Warning>
  **Current limitations**:

  * **Max execution time**: 15 minutes per run
  * **Max steps**: Configurable, default 40
  * **Declarative only**: Agents use instructions, not imperative code
  * **State in memory**: All state must be stored in memory
  * **No async actions**: Parallel execution coming soon
</Warning>

## Next Steps

<CardGroup cols={2}>
  <Card title="Actions" icon="bolt" href="/core/actions">
    Learn how to build powerful actions
  </Card>

  <Card title="Memory" icon="database" href="/core/memory">
    Master memory operations
  </Card>

  <Card title="Strategies" icon="chess" href="/strategies/overview">
    Add manual approval and wait conditions
  </Card>

  <Card title="Deployment" icon="rocket" href="/deployment">
    Deploy and invoke your agents
  </Card>
</CardGroup>
