> ## Documentation Index
> Fetch the complete documentation index at: https://notte-experiment-visibility-md-links.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent to Function Conversion

> Convert agent executions into reusable function code

Convert successful agent runs into deterministic function code that can be executed faster and cheaper than agents.

## Overview

After an agent completes a task, you can extract the steps as function code:

{/* @sniptest testers/agents/workflows/overview.py */}

```python theme={null}
from notte_sdk import NotteClient

client = NotteClient()

with client.Session() as session:
    agent = client.Agent(session=session)
    result = agent.run(task="Navigate to pricing page and extract plans")

    if result.success:
        # Convert to function code
        function_code = agent.workflow.code()
        print(function_code.python_script)
```

## Why Convert to Functions?

| Aspect           | Agent                  | Function                  |
| ---------------- | ---------------------- | ------------------------- |
| **Execution**    | AI decides each step   | Predefined steps          |
| **Speed**        | Slower (LLM reasoning) | Faster (direct execution) |
| **Cost**         | Higher (LLM tokens)    | Lower (actions only)      |
| **Reliability**  | Can vary               | Deterministic             |
| **Adaptability** | Handles changes        | Breaks if page changes    |

**Use functions when:**

* The task is well-defined and repeatable
* Page structure is stable
* Speed and cost matter
* You need predictable execution

## Getting Function Code

### As Python Script

Get executable Python code:

{/* @sniptest testers/agents/workflows/get-python-script.py */}

```python get-python-script.py theme={null}
agent = client.Agent(session=session)
result = agent.run(task="Login and navigate to dashboard")

if result.success:
    # Get function code
    code = agent.workflow.code(as_workflow=True)

    print(code.python_script)
```

Example output:

{/* @sniptest testers/agents/workflows/example-output.py */}

```python theme={null}
from notte_sdk import NotteClient

client = NotteClient()

with client.Session() as session:
    # Step 1: Navigate to login page
    session.execute(type="goto", url="https://example.com/login")

    # Step 2: Fill email field
    session.execute(type="fill", selector="input[name='email']", value="user@example.com")

    # Step 3: Fill password field
    session.execute(type="fill", selector="input[name='password']", value="********")

    # Step 4: Click login button
    session.execute(type="click", selector="button[type='submit']")

    # Step 5: Wait for dashboard
    session.execute(type="goto", url="https://example.com/dashboard")
```

### As Function Object

Create a reusable function:

{/* @sniptest testers/agents/workflows/create-function-object.py */}

```python create-function-object.py theme={null}
result = agent.run(task="Extract product data")

if result.success:
    # Create function from agent
    function = agent.workflow.create_function()

    print(f"Created function: {function.function_id}")

    # Run function later
    function_result = function.run()
```

## Running Functions

### Execute Generated Code

Copy and run the generated Python:

{/* @sniptest testers/agents/workflows/execute-generated-code.py */}

```python theme={null}
# Generated from agent
from notte_sdk import NotteClient

client = NotteClient()

with client.Session() as session:
    session.execute(type="goto", url="https://example.com")
    session.execute(type="click", selector="button.search")
    session.execute(type="fill", selector="input[name='query']", value="laptop")
    data = session.scrape(instructions="Extract product names")

print(data)
```

### Use Function API

Run via the function endpoint:

{/* @sniptest testers/agents/workflows/use-function-api.py */}

```python use-function-api.py theme={null}
agent.run(task="Complete task")

# Create function from successful agent
function = agent.workflow.create_function()

# Run multiple times
for query in ["laptop", "phone", "tablet"]:
```

## Use Cases

### 1. Prototyping with Agents

Use agents to figure out the automation, then convert:

{/* @sniptest testers/agents/workflows/prototyping-with-agents.py */}

```python prototyping-with-agents.py theme={null}
# Phase 1: Prototype with agent
agent = client.Agent(session=session)
result = agent.run(task="Find all products under $100")

if result.success:
    # Phase 2: Convert to function for production
    code = agent.workflow.code()

    # Save for production use
    with open("production_function.py", "w") as f:
        f.write(code.python_script)
```

### 2. Scheduled Tasks

Convert one-time agent runs to scheduled functions:

{/* @sniptest testers/agents/workflows/scheduled-tasks.py */}

```python scheduled-tasks.py theme={null}
agent = client.Agent(session=session)
result = agent.run(task="Extract daily price changes")

# Convert to function
function = agent.workflow.create_function()

# Schedule to run daily (via API or console)
# function.schedule(cron="0 9 * * *")
```

### 3. Cost Optimization

Run agents once, then use cheaper functions:

{/* @sniptest testers/agents/workflows/cost-optimization.py */}

```python cost-optimization.py theme={null}
agent = client.Agent(session=session)
result = agent.run(task="Complex data extraction")

# Recurring: Use function ($0.05 per run)
function = agent.workflow.create_function()

# Run 100 times - save $15 vs running agent each time
for i in range(100):
    function.run()
```

### 4. Testing Variations

Create function templates from agents:

{/* @sniptest testers/agents/workflows/testing-variations.py */}

```python testing-variations.py theme={null}
# Base workflow from agent
agent = client.Agent(session=session)
result = agent.run(task="Search and extract results")

code = agent.workflow.code()

# Modify code for variations
# - Different search queries
# - Different extraction logic
# - Different URLs
```

## Customizing Generated Code

### Add Parameters

Make functions reusable with parameters:

{/* @sniptest testers/agents/workflows/add-parameters.py */}

```python add-parameters.py theme={null}
    # Agent-generated base code
    code = agent.workflow.code()

    # Customize with parameters
    customized_code = f"""
def extract_products(search_query: str, max_results: int = 10):
    {code.python_script}
"""
```

### Add Error Handling

Enhance with production-ready error handling:

{/* @sniptest testers/agents/workflows/add-error-handling.py */}

```python add-error-handling.py theme={null}
    # Agent-generated code
    base_code = agent.workflow.code()

    enhanced_code = f"""
from notte_sdk import NotteClient
from loguru import logger

def run_function():
    client = NotteClient()
    try:
        with client.Session() as session:
            {base_code.python_script}
            return {{"success": True, "data": result}}
    except Exception as e:
        logger.error(f"Function failed: {{e}}")
```

### Optimize Selectors

Review and improve generated selectors:

{/* @sniptest testers/agents/workflows/optimize-selectors.py */}

```python optimize-selectors.py theme={null}
# Generated code might use:
session.execute(type="click", selector="div.container > button:nth-child(3)")

# Optimize to:
session.execute(type="click", selector="button[data-testid='submit']")
```

## Best Practices

### 1. Test Generated Functions

Always test before production:

{/* @sniptest testers/agents/workflows/test-generated-functions.py */}

```python test-generated-functions.py theme={null}
    agent.run(task="Complete task")

    # Generate function code
    code = agent.workflow.code()

# Test in fresh session
with client.Session() as session:
    exec(code.python_script)
```

### 2. Document the Source

Track which agent generated the function:

{/* @sniptest testers/agents/workflows/document-the-source.py */}

```python document-the-source.py theme={null}
result = agent.run(task="Extract product data")

function = agent.workflow.create_function()

# Add metadata
metadata = {
    "agent_id": agent.agent_id,
    "original_task": "Extract product data",
    "created_at": datetime.now().isoformat(),
    "success_rate": result.success,
}
```

### 3. Version Control

Store functions in git:

{/* @sniptest testers/agents/workflows/version-control.py */}

```python version-control.py theme={null}
agent = client.Agent(session=session)
agent.run(task="Extract products")

# Save function code
code = agent.workflow.code()

function_path = Path("functions/extract_products.py")
function_path.parent.mkdir(exist_ok=True)
```

### 4. Monitor Function Success

Track if functions continue to work:

{/* @sniptest testers/agents/workflows/monitor-function-success.py */}

```python theme={null}
from datetime import datetime


def run_monitored_function():
    try:
        function = client.Function(function_id="func_abc123")
        result = function.run()

        if result.status == "closed":
            log_success(datetime.now())
        else:
            alert_failure(result.result)

    except Exception as e:
        # Function broken - maybe page changed?
        # Time to re-run agent and regenerate
        alert_function_broken(e)
```

### 5. Regenerate When Pages Change

When functions break, use agents to update:

{/* @sniptest testers/agents/workflows/regenerate-when-pages-change.py */}

```python regenerate-when-pages-change.py theme={null}
# Old function failing
try:
    old_function.run()
except Exception:
    print("Function broken, regenerating...")

    with client.Session() as session:
        # Use agent to figure out new function
        agent = client.Agent(session=session)
        result = agent.run(task=original_task_description)

        if result.success:
            # Generate new function
```

## Limitations

Functions work best for:

* ✅ Stable, unchanging pages
* ✅ Deterministic tasks
* ✅ Known sequences of actions

Functions are not suitable for:

* ❌ Pages that change frequently
* ❌ Tasks requiring adaptation
* ❌ Complex decision-making

When pages change or tasks become complex, revert to agents.

## Next Steps

<CardGroup cols={2}>
  <Card title="Functions" icon="function" href="/concepts/functions.md">
    Deploy automations as serverless APIs
  </Card>

  <Card title="Actions" icon="hand-pointer" href="/sdk-reference/manual/session.md">
    Available session actions
  </Card>

  <Card title="Agent Configuration" icon="sliders" href="/features/agents/configuration.md">
    Optimize agent runs
  </Card>

  <Card title="Functions" icon="flower" href="/concepts/functions.md">
    Deploy and manage serverless functions
  </Card>
</CardGroup>
