# Agent components

> Agent components - This overview details the components required to create an agent using
> DataRobot's agent framework.

This Markdown file sits beside the HTML page at the same path (with a `.md` suffix). It summarizes the topic and lists links for tools and LLM context.

Companion generated at `2026-04-24T16:03:56.224844+00:00` (UTC).

## Primary page

- [Agent components](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html): Full documentation for this topic (HTML).

## Sections on this page

- [Agent file structure](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#agent-file-structure): In-page section heading.
- [Agent metadata (model-metadata.yaml)](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#agent-metadata-model-metadata-yaml): In-page section heading.
- [Functions and hooks (custom.py)](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#functions-and-hooks-custom-py): In-page section heading.
- [load_model()hook](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#load-model-hook): In-page section heading.
- [chat()hook](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#chat-hook): In-page section heading.
- [Agent class implementation (myagent.py)](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#agent-class-implementation-myagent-py): In-page section heading.
- [__init__()method](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#init-method): In-page section heading.
- [invoke()method](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#invoke-method): In-page section heading.
- [llmproperty](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#llm-property): In-page section heading.
- [Tool integration](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#tool-integration): In-page section heading.
- [Framework-specific tools](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#framework-tools): In-page section heading.
- [Authorization context](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-overview.html#authorization-context): In-page section heading.

## Related documentation

- [Agentic AI](https://docs.datarobot.com/en/docs/agentic-ai/index.html): Linked from this page.
- [Build](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/index.html): Linked from this page.
- [structured model hooks documentation](https://docs.datarobot.com/en/docs/api/code-first-tools/drum/structured-custom-models.html): Linked from this page.
- [Configure LLM providers in code](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-llm-providers.html#datarobot-hosted-llm-deployments): Linked from this page.

## Documentation content

# Agent components

This overview details the components required to create an agent using DataRobot's agent framework. An agent artifact includes several standard files that contain metadata, hooks/functions, classes, and properties.

| Section | Description |
| --- | --- |
| Agent file structure | Describes important files and their organization for a DataRobot agent. |
| Functions and hooks | Details the mandatory functions and integration hooks needed for agent operation. |
| Agent class implementation | Details the general structure of the main agent class and its methods and properties. |
| Tool integration | Explains how agents use tools via the ToolClient class and framework-specific tool APIs. |

## Agent file structure

Every DataRobot agent requires a specific set of files in the `agent/agent/` directory (for example, in the [DataRobot Agentic Starter template](https://github.com/datarobot-community/datarobot-agent-application)). These files work together to create a complete agent that can be deployed and executed by DataRobot.

```
# agent/agent/ directory
agent/agent/
├── __init__.py           # Package initialization
├── myagent.py            # Main agent implementation, including prompts
├── custom.py             # DataRobot integration hooks
├── config.py             # Configuration management
├── mcp_client.py         # MCP server integration (optional, for tool use)
└── model-metadata.yaml   # Agent metadata configuration
```

| File | Description |
| --- | --- |
| __init__.py | Identifies the directory as a Python package and enables imports. |
| model-metadata.yaml | Defines the agent's configuration, runtime parameters, and deployment settings. |
| custom.py | Implements DataRobot integration hooks (load_model, chat) for agent execution. |
| myagent.py | Contains the main MyAgent class with core workflow logic and framework-specific implementation. |
| config.py | Manages configuration loading from environment variables, runtime parameters, and DataRobot credentials. |
| mcp_client.py | Provides MCP server connection management for tool integration (optional, only needed when using MCP tools). |

### Agent metadata (model-metadata.yaml)

The `model-metadata.yaml` file tells DataRobot how to configure and deploy the agent. It defines the agent's type, name, and any required runtime parameters.

```
# model-metadata.yaml
---
name: agent_name
type: inference
targetType: agenticworkflow
runtimeParameterDefinitions:
  - fieldName: LLM_DEPLOYMENT_ID
    defaultValue: SET_VIA_PULUMI_OR_MANUALLY
    type: string
  - fieldName: LLM_DEFAULT_MODEL
    defaultValue: SET_VIA_PULUMI_OR_MANUALLY
    type: string
  - fieldName: LLM_DEFAULT_MODEL_FRIENDLY_NAME
    defaultValue: SET_VIA_PULUMI_OR_MANUALLY
    type: string
  - fieldName: USE_DATAROBOT_LLM_GATEWAY
    defaultValue: SET_VIA_PULUMI_OR_MANUALLY
    type: string
  - fieldName: MCP_DEPLOYMENT_ID
    defaultValue: SET_VIA_PULUMI_OR_MANUALLY
    type: string
  - fieldName: EXTERNAL_MCP_URL
    defaultValue: SET_VIA_PULUMI_OR_MANUALLY
    type: string
  - fieldName: SESSION_SECRET_KEY
    defaultValue: SET_VIA_PULUMI_OR_MANUALLY
    type: string
```

| Field | Description |
| --- | --- |
| name | The agent's display name in DataRobot (used for identification and deployment). |
| type | The agent model type. Must be inference for all DataRobot agents. |
| targetType | The agent target type. Must be agenticworkflow for agentic workflow deployments. |
| runtimeParameterDefinitions | Defines optional runtime parameters for LLM configuration, MCP server connections, and other agent settings. |

> [!TIP] LLM Provider Configuration
> Agents support multiple LLM provider configurations including:
> 
> LLM gateway direct
> : Use DataRobot's LLM gateway directly
> LLM blueprint with external LLMs
> : Connect to external providers (Azure OpenAI, Amazon Bedrock, Google Vertex AI, Anthropic, Cohere, TogetherAI)
> Deployed models
> : Use a DataRobot-deployed LLM via
> LLM_DEPLOYMENT_ID
> 
> When you use the DataRobot Deployed LLM option, `USE_DATAROBOT_LLM_GATEWAY` is automatically set to `0` so the workflow targets your deployment instead of the gateway.

## Functions and hooks (custom.py)

Agents use specific function signatures called "hooks" to integrate with DataRobot. The `custom.py` file contains the required functions that DataRobot calls to execute the agent. These functions connect DataRobot and the agent's logic. For more information, see the [structured model hooks documentation](https://docs.datarobot.com/en/docs/api/code-first-tools/drum/structured-custom-models.html). The following DataRobot custom model hooks are implemented in `custom.py`:

| Component | Description |
| --- | --- |
| load_model() | One-time initialization function called when DataRobot starts the agent. |
| chat() | Main execution function called for each user interaction/chat message. |

> [!TIP] Other DataRobot hooks
> The `score()` and `score_unstructured()` functions can be implemented if required for specific use cases.

### load_model() hook

The `load_model()` hook is called once to initialize the agent. This is where any one-time configuration can be defined.

```
# custom.py
def load_model(code_dir: str) -> tuple[ThreadPoolExecutor, asyncio.AbstractEventLoop]:
    """The agent is instantiated in this function and returned.

    Args:
        code_dir: Path to the agentic workflow directory

    Returns:
        tuple[ThreadPoolExecutor, asyncio.AbstractEventLoop]: Thread pool executor and event loop for async operations
    """
    thread_pool_executor = ThreadPoolExecutor(1)
    event_loop = asyncio.new_event_loop()
    thread_pool_executor.submit(asyncio.set_event_loop, event_loop).result()
    return (thread_pool_executor, event_loop)
```

### chat() hook

The main entry point for the agent. DataRobot calls this function every time a user sends a message to the agent.

```
# custom.py
def chat(
    completion_create_params: CompletionCreateParams
    | CompletionCreateParamsNonStreaming
    | CompletionCreateParamsStreaming,
    load_model_result: tuple[ThreadPoolExecutor, asyncio.AbstractEventLoop],
    **kwargs: Any,
) -> Union[CustomModelChatResponse, Iterator[CustomModelStreamingResponse]]:
    """Main entry point for agent execution via chat endpoint.

    Args:
        completion_create_params: OpenAI-compatible completion parameters
        load_model_result: Result from load_model() function
        **kwargs: Additional keyword arguments (e.g., headers)

    Returns:
        Union[CustomModelChatResponse, Iterator[CustomModelStreamingResponse]]: Formatted response with agent output
    """
```

## Agent class implementation (myagent.py)

The `myagent.py` file contains the `MyAgent` class to implement the workflow logic. This is where you define how the agent behaves, the tools it uses, and how it processes inputs.

| Component | Description |
| --- | --- |
| init() | Method to initialize the agent with credentials, configuration, and framework-specific setup. |
| invoke() | Main execution method that processes inputs and returns framework-specific results. |
| llm or llm() | Property or method (depending on framework template) that returns the configured LLM instance for agent operations. |

Every agent follows this basic pattern, though the specific implementation varies by framework.

> [!NOTE] Framework-specific implementations
> CrewAI, LangGraph, LlamaIndex, and NAT (NVIDIA NeMo Agent Toolkit) templates include framework-specific `llm` or `llm()` implementations and return types. The Generic Base template provides a minimal implementation that can be customized for any framework. NAT templates configure LLMs in `workflow.yaml` rather than through Python `llm` configuration.

```
# myagent.py
class MyAgent:
    """Agent implementation following DataRobot patterns."""

    def __init__(
        self,
        api_key: Optional[str] = None,
        api_base: Optional[str] = None,
        model: Optional[str] = None,
        verbose: Optional[Union[bool, str]] = True,
        timeout: Optional[int] = 90,
        **kwargs: Any,
    ):
        """Initialize agent with credentials and configuration."""
        self.api_key = api_key or os.environ.get("DATAROBOT_API_TOKEN")
        self.api_base = api_base or os.environ.get("DATAROBOT_ENDPOINT")
        self.model = model
        self.timeout = timeout
        # ... other initialization

    @property
    def llm(self) -> LLM:  # Framework-specific type
        """Primary LLM configuration."""
        if os.environ.get("LLM_DEPLOYMENT_ID"):
            return self.llm_with_datarobot_deployment
        else:
            return self.llm_with_datarobot_llm_gateway

    def invoke(self, completion_create_params: CompletionCreateParams) -> Union[
        Generator[tuple[str, Any | None, dict[str, int]], None, None],
        tuple[str, Any | None, dict[str, int]],
    ]:
        """Main execution method - REQUIRED."""
        # Extract inputs
        inputs = create_inputs_from_completion_params(completion_create_params)

        # Execute agent workflow

        # Return results
        return response_text, pipeline_interactions, usage_metrics
```

### __init__() method

The method that initializes the agent with configuration and credentials from DataRobot and  framework-specific setup.

```
# myagent.py
class MyAgent:
    def __init__(self, api_key: Optional[str] = None, 
                 api_base: Optional[str] = None,
                 model: Optional[str] = None,
                 verbose: Optional[Union[bool, str]] = True,
                 timeout: Optional[int] = 90,
                 **kwargs: Any):
        """Initialize agent with DataRobot credentials and configuration."""
```

### invoke() method

The core execution method that DataRobot calls to run the agent. This method must be implemented and should contain the agent's main workflow logic. All frameworks use the same return type pattern.

```
# myagent.py
    def invoke(self, completion_create_params: CompletionCreateParams) -> Union[
        Generator[tuple[str, Any | None, dict[str, int]], None, None],
        tuple[str, Any | None, dict[str, int]],
    ]:
        """Main execution method - REQUIRED for DataRobot integration.

        Args:
            completion_create_params: Input parameters from DataRobot

        Returns:
            Union of generator (for streaming) or tuple (for non-streaming):
            - response_text: str - The agent's response
            - pipeline_interactions: Any | None - Event tracking data
            - usage_metrics: dict[str, int] - Token usage statistics
        """
```

### llm property

Defines which language model the agent uses for generating responses. The return type and implementation varies by framework.

The CrewAI, LangGraph, and LlamaIndex templates implement API base URL logic directly within their `llm` properties:

```
# myagent.py (CrewAI/LangGraph/LlamaIndex)
@property
def llm(self) -> LLM:  # Framework-specific type
    """Primary LLM instance for agent operations.

    Returns:
        Framework-specific LLM type:
        - CrewAI: LLM
        - LangGraph: ChatLiteLLM  
        - LlamaIndex: DataRobotLiteLLM
    """
    api_base = urlparse(self.api_base)
    if os.environ.get("LLM_DEPLOYMENT_ID"):
        # Handle deployment-specific URL construction
        # ... implementation details ...
        return LLM(model="openai/gpt-4o-mini", api_base=deployment_url, ...)
    else:
        # Handle LLM gateway URL construction
        # ... implementation details ...
        return LLM(model="datarobot/azure/gpt-5-mini-2025-08-07", api_base=api_base.geturl(), ...)
```

The Generic Base template implements the `llm` property as follows:

```
# myagent.py (Generic Base)
@property
def llm(self) -> Any:
    """Primary LLM instance for agent operations.

    Returns:
        Any: Minimal implementation for custom frameworks
    """
    if os.environ.get("LLM_DEPLOYMENT_ID"):
        return self.llm_with_datarobot_deployment
    else:
        return self.llm_with_datarobot_llm_gateway
```

The NAT template configures LLMs in `workflow.yaml` rather than through a Python property. You can use the DataRobot LLM gateway ( `_type: datarobot-llm-gateway`), DataRobot deployments ( `_type: datarobot-llm-deployment`), or DataRobot NIM deployments ( `_type: datarobot-nim`). The example below uses the DataRobot LLM gateway:

```
# workflow.yaml (NAT)
llms:
    datarobot_llm:
    _type: datarobot-llm-gateway
    model_name: azure/gpt-4o-mini  # Define the model name you want to use
    temperature: 0.0
```

The LLM a specific agent uses is defined through the `llm_name` in the definition of that agent in the `functions` section:

```
# workflow.yaml (NAT)
functions:
    planner:
    _type: chat_completion
    llm_name: datarobot_llm  # Reference the LLM defined above
    system_prompt: |
        You are a content planner...
```

If more than one LLM is defined in the `llms` section, the various `functions` can use different LLMs to suit the task.

> [!TIP] NAT-provided LLM interfaces
> Alternatively, you can use any of the [NAT-provided LLM interfaces](https://docs.nvidia.com/nemo/agent-toolkit/latest/workflows/llms/index.html) instead of the LLM gateway. To use a NAT LLM interface, add the required configuration parameters such as `api_key`, `url`, and other provider-specific settings directly in the `workflow.yaml` file.

For information about using DataRobot deployments with NAT templates, see [Configure LLM providers in code](https://docs.datarobot.com/en/docs/agentic-ai/agentic-develop/agentic-llm-providers.html#datarobot-hosted-llm-deployments).

## Tool integration

Agents can use tools to extend their capabilities with the `ToolClient` class, which enables agents to call DataRobot tool deployments. The functionality of `helpers.py` present in previous versions was moved to the [datarobot-genaipackage](https://github.com/datarobot-oss/datarobot-genai) along with other adapter code that connects agents to DataRobot's DRUM server in version 11.3.1.

> [!NOTE] ToolClient usage consideration
> The `ToolClient` is specifically designed for calling user-deployed global tools within DataRobot. As this client serves that specialized use case, it is not required for the majority of agent tool implementations.

### Framework-specific tools

Each framework provides its own native tool APIs for defining custom tools:

- CrewAI : Tools are passed to Agent instances via the tools parameter.
- LangGraph : Tools are defined as part of graph nodes and edges.
- LlamaIndex : Tools are defined as functions and passed to agent constructors.
- NAT : Tools are defined in workflow.yaml as functions and referenced in the workflow's tool_list (the available tool types are defined by thenat_toolsubmodules ).

> [!TIP] NAT agent configuration
> Use [react_agent](https://docs.nvidia.com/nemo/agent-toolkit/latest/workflows/about/react-agent.html) instead of [sequential_executor](https://docs.nvidia.com/nemo/agent-toolkit/latest/workflows/about/sequential-executor.html) for flexible agents that decide which tools to run in which order, depending on the query.

### Authorization context

The `resolve_authorization_context()` function from the `datarobot-genai` package is called in `custom.py` to automatically handle authentication for tools that require access tokens. The function returns an authorization context dictionary that is assigned to `completion_create_params["authorization_context"]`. This ensures tools can securely access external services using DataRobot's credential management system.
