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

# Agent Composer YAML

> Configuring the Agent Composer YAML file

<Note>
  Custom Agent Composer YAML workflows are available in public preview for enterprise users. Template agents (Basic Search and Agentic Search) are available for self-serve users, but creating custom workflows with YAML requires enterprise access. For more information or to request access, please contact your Contextual AI representative.
</Note>

## Overview

The Agent Composer YAML lets you define **executable agent workflows** as graphs. Each workflow describes:

* What inputs it accepts,
* How data flows between steps (nodes),
* What outputs it produces,
* What is surfaced to the UI

A workflow is compiled into an `ExecutableGraph` and run via the `/query/acl` API.

<Note>
  The following resources can also aid you in building Agent Composer workflows via YAML:

  <ul>
    <li><a href="/how-to-guides/ac-yaml-reference">Agent Composer YAML Reference Catalog</a></li>
    <li><a href="/how-to-guides/ac-yaml-cheatsheet">Agent Composer YAML Cheatsheet</a></li>
  </ul>
</Note>

***

## A Minimal Workflow Example

The following is the smallest useful Agent Composer YAML. You can copy/paste this and run it immediately.

```yaml theme={null}
inputs:
  query: str

outputs:
  response: str

nodes:
  generate:
    type: ResponseGenerationStep
    input_mapping:
      query: __inputs__#query

  __outputs__:
    type: output
    input_mapping:
      response: generate#response
```

Here's what it does:

* Accepts a single input: `query`
* Runs a generation step
* Returns a single output: `response`
* Automatically displays `response` in the UI

***

## An Extended Workflow Example

The following workflow defines a retrieval-augmented question-answering pipeline that takes a user query, builds conversational context, performs structured agentic research over a vectorized document datastore, and generates a grounded response strictly based on retrieved evidence.

```yaml theme={null}
version: 0.1
inputs:
  query: str

outputs:
  response: str

nodes:
  create_message_history:
    type: CreateMessageHistoryStep
    input_mapping:
      query: __inputs__#query

  research:
    type: AgenticResearchStep
    ui_stream_types:
      retrievals: true
    config:
      tools_config:
        - name: search_docs
          description: |
            Search the datastore containing user-uploaded documents. This datastore is a vector database of text chunks which uses hybrid semantic and lexical search to find the most relevant chunks.
            Use this tool to find information within the uploaded documents.
          step_config:
            type: SearchUnstructuredDataStep
            config:
              top_k: 50 # Retrieve 50 chunks from vector search
              lexical_alpha: 0.1          # Weight for lexical (BM25) search
              semantic_alpha: 0.9         # Weight for semantic (vector) search
              reranker: "ctxl-rerank-v2-instruct-multilingual-FP8"
              rerank_top_k: 12
              reranker_score_filter_threshold: 0.2

      agent_config:
        agent_loop:
          num_turns: 10
          parallel_tool_calls: false
          model_name_or_path: "vertex_ai/claude-opus-4-5@20251101"
          identity_guidelines_prompt: |
            You are a retrieval-augmented assistant created by Contextual AI. You provide factual, grounded answers to user's questions by retrieving information via tools and then synthesizing a response based only on what you retrieved.

          research_guidelines_prompt: |
            You have access to the following tool:
            - `search_docs` — Search the document datastore. Returns SEARCH_RESULTS with CITE_ID for citation.
            
            You have access to the following data source:
            1. Document Datastore (Unstructured): 
                - Contains user-uploaded documents that have been parsed, extracted, and chunked for efficient retrieval.
                - Use the `search_docs` tool to query this datastore for relevant content, details, and information from the available documents.
            
            ## Research Strategy
            You MUST always explore unstructured datastore before answering. Do not skip the source.
            - Breadth, then depth strategy:
                1. INITIAL RETRIEVAL - FIRST (Mandatory):
                  - Documents: Use `search_docs` with your initial search terms.
                2. ANALYZE & PLAN: Review initial results and create a query plan:
                  - What information is still missing to fully answer the question?
                  - Create a specific plan: which queries to run next and in what order
                  - Identify dependencies: what do you need to find first before searching for related info?
                3. DEEP DIVE (Execute & Adapt): Execute your plan and adapt based on retrieved content:
                  - Run planned queries systematically
                  - Continue until you have a COMPLETE answer - don't stop early
            - EFFICIENCY: You have 10 turns. Be strategic:
                - Avoid redundant searches; prefer high-quality retrievals.
                - Batch related searches when possible
                - Don't repeat similar queries
                - Prioritize high-value retrievals first
                - But DO NOT sacrifice comprehensiveness for speed - gather ALL relevant information

    input_mapping:
      message_history: create_message_history#message_history

  generate:
    type: GenerateFromResearchStep
    ui_stream_types:
      generation: true
    config:
      model_name_or_path: "vertex_ai/claude-opus-4-5@20251101"

      identity_guidelines_prompt: |
        You are a retrieval-augmented assistant created by Contextual AI. Your purpose is to provide factual, grounded answers by retrieving information via tools and then synthesizing a response based only on what you retrieved. Always start immediately with the answer, don't begin with a preamble or thoughts. 

      response_guidelines_prompt: |
        ## Output
        - Write a concise, direct, well-structured answer in **Markdown** (use short headings, bullets, and brief paragraphs).
        - **START IMMEDIATELY WITH THE ANSWER.** Never begin with preamble like:
          - "Perfect!", "Great!", "Based on my research...", "I now have comprehensive information..."
          - "Let me provide...", "I can now provide...", "Here's what I found..."
          - Any meta-commentary about your search process or confidence level
        - Your first words should be the actual content (a heading, the direct answer, or the key fact).
        - If the required fact is missing from the latest **SEARCH_RESULTS**:
          - Partial or Related Information: Provide whatever relevant details you found, while clearly stating the limitations or gaps.
          - No Relevant Information: If nothing related was found, reply with: "I don't have specific information about [topic] in the available documents."
          - Maintain Engagement: Suggest related topics or alternative ways you can assist to keep the interaction productive.
        - DO NOT engage in character play. You must maintain a friendly, professional, and neutral tone at all times.

    input_mapping:
      message_history: create_message_history#message_history
      research: research#research

  __outputs__:
    type: output
    input_mapping:
      response: generate#response
```

This workflow enforces a disciplined research strategy—mandatory document retrieval, iterative planning, and deep dives—using a hybrid semantic-lexical search with reranking for precision, followed by a constrained generation step that produces concise, well-structured Markdown answers without meta commentary or speculation.

***

## YAML Schema (Root-level Fields)

Every Agent Composer YAML file defines a `graph` with the following root fields:

| Field       | Required | Description                                 |
| ----------- | -------- | ------------------------------------------- |
| `inputs`    | ✅        | Graph inputs and their Python types         |
| `outputs`   | ✅        | Graph outputs (must be JSON-serializable)   |
| `nodes`     | ✅        | Nodes and their connections                 |
| `ui_output` | ⚠️       | Required only if there are multiple outputs |

### Important Constraints

* The **root graph currently accepts only one input:** `query: str` (unless the graph is used as a subgraph).
* Graph outputs must be **JSON-serializable**, as they are returned by the API.
* If **more than one output exists**, exactly one must be selected as `ui_output`.

**Example:**

```yaml theme={null}
ui_output: response
```

***

## Wiring & Mapping Syntax

Nodes are connected using **output references** of the form:

```yaml theme={null}
node_name#output_key
```

### Special Nodes

* `__inputs__`
  Represents graph inputs defined under inputs.
* `__outputs__`
  Explicitly maps node outputs to graph outputs.

### Example Wiring

```yaml theme={null}
input_mapping:
  query: __inputs__#query
  processed_query: preprocess#output
```

Conceptually:

**inputs**.query → preprocess.output → finalize.response → **outputs**.response

***

## Nodes

A node represents a single operation in the graph with the following standard structure:

```yaml theme={null}
example_node:
  type: SomeStepType
  config:
    some_param: 0.5
  input_mapping:
    input_name: upstream_node#output
```

### Node Fields

* `type` (required): The step type (must be registered in the system).
* `input_mapping` (required if inputs exist): Wires node inputs to outputs from other nodes.
* `config` (optional): Static configuration passed at graph construction time.
* `config_overrides` (optional): Dynamic configuration resolved at execution time.
* `ui_stream_types` (optional): Controls what this node streams to the UI.

<Note>All declared inputs of a node must be connected, or graph validation will fail.</Note>

### Node Types

| Node Type      | Steps                                                                                                                                                                                                                                                                                                |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Primitive**  | `InputNode`, `OutputNode`, `ConditionalStep`, `PassThroughStep`, `GetMemberStep`, `SetMemberStep`, `ConstantStep`, `WrapStep`, `JSONCreatorStep`, `IsFirstTurnStep`, `SliceStep`, `LengthStep`, `IndexStep`, `AppendStep`, `ConcatenateStep`, `MergeStep`, `MergeRetrievalsStep`, `DeleteMemberStep` |
| **Retrieval**  | `FileAnalysisInputStep`, `ContextualAgentStep`, `SearchStructuredDataStep`, `SearchUnstructuredDataStep`, `QueryStructuredDatastoreStep`, `GetStructuredDatastoreSchemaStep`, `ReformulateQueryStep`, `MetadataSearchStep`                                                                           |
| **Tool**       | `WebSearchStep`, `CodeExecutionStep`, `MCPClientStep`, `SalesforceSOSLStep`                                                                                                                                                                                                                          |
| **Utilities**  | `LanguageModelStep`, `WebhookStep`, `CreateMessageHistoryStep`                                                                                                                                                                                                                                       |
| **Agent**      | `AgenticResearchStep`, `GenerateFromResearchStep`                                                                                                                                                                                                                                                    |
| **generation** | `ResponseGenerationStep`, `ResponseGenFromResearchStep`, `PreHookStep`, `PostHookStep`                                                                                                                                                                                                               |

***

## Dynamic Configuration Overrides

`config_overrides` allow node configuration to be set dynamically at runtime.

```yaml theme={null}
search:
  type: SearchUnstructuredDataStep
  config:
    filter_retrievals: true
  config_overrides:
    top_k: __inputs__#top_k
  input_mapping:
    query: __inputs__#query
```

The following rules apply to dynamic configuration overrides:

* Overrides are merged with static `config`
* Overrides can come from **any node output**
* Nodes whose type has `OUTPUTS = None` cannot use config overrides

***

## Output Node

Every graph must explicitly define how node outputs map to graph outputs.

```yaml theme={null}
__outputs__:
  type: output
  input_mapping:
    response: generate#response
```

The output node:

* Has no config
* Has no outputs of its own
* Only maps values into graph outputs

***

## UI Streaming

Some nodes can stream events to the UI (retrievals, generation, etc.).

```yaml theme={null}
generate:
  type: ResponseGenerationStep
  ui_stream_types:
    generation: true
```

Bear in mind the following in regards to UI streaming:

* Each step type declares supported stream types and defaults
* Multiple nodes may stream the same type
* Streaming is independent of the final `ui_output`

***

## Subgraphs

Subgraphs are reusable workflows that can be embedded as nodes in other graphs.

You can think of a subgraph like a function:

* inputs = parameters
* outputs = return values
* nodes = function body

### Defining a Subgraph

```yaml theme={null}
document_retrieval:
  inputs:
    query: str
  outputs:
    documents: List[str]
  nodes:
    search:
      type: SearchStep
      input_mapping:
        query: __inputs__#query

    __outputs__:
      type: output
      input_mapping:
        documents: search#documents
```

### Using a Subgraph

```yaml theme={null}
retriever:
  type: subgraph:document_retrieval
  input_mapping:
    query: __inputs__#query
```

Bear in mind the following regarding subgraphs:

* Subgraphs can be nested
* Subgraphs can be reused multiple times
* Subgraphs have isolated input/output scopes

***

## Conditional Execution

Conditional nodes execute **exactly one branch** based on a condition.

```yaml theme={null}
conditional:
  type: ConditionalStep
  config:
    inputs:
      score: float
    outputs:
      result: str
    variable: score
    branches:
      - condition: ">= 0.8"
        executable: HighQualityProcessor
        output_mapping:
          __outputs__#result: processed
      - condition: "< 0.8"
        executable: LowQualityProcessor
        output_mapping:
          __outputs__#result: processed
  input_mapping:
    score: evaluator#score
```

Bear in mind the following rules regarding conditional execution:

* Conditions are evaluated top-to-bottom
* First matching branch is executed
* `__inputs__` inside a branch refers to conditional inputs, not graph inputs

***

## Agentic Research & Tool Usage

Agentic behavior in Agent Composer is implemented using **explicit agentic steps** that separate **research (tool use and planning)** from **final response generation**. This pattern makes agent workflows easier to reason about, debug, and control, while ensuring responses remain grounded in retrieved information.
A typical agentic workflow consists of three phases:

1. `CreateMessageHistoryStep` – Initialize structured conversation state
2. `AgenticResearchStep` – Perform multi-turn research using tools
3. `GenerateFromResearchStep` – Generate a final response grounded in research results

### Initializing Message History

The following step converts the raw user input into a structured `message_history` object. This standardized message format is required by agentic steps and ensures consistent conversational context throughout the workflow.

```yaml theme={null}
create_message_history:
  type: CreateMessageHistoryStep
  input_mapping:
    query: __inputs__#query
```

This step:

* Transforms the user’s `query` into a structured message format
* Establishes a consistent conversation state
* Produces `message_history`, which is reused by both research and generation steps

### Agentic Research Step

The following step runs an internal agent loop that plans, executes, and adapts retrieval strategies over multiple turns. It is responsible for all tool usage and information gathering.

```yaml theme={null}
research:
  type: AgenticResearchStep
  ui_stream_types:
    retrievals: true
```

This step:

* Controls the agent’s reasoning and decision-making process
* Determines when and how tools are invoked
* Iteratively retrieves information until sufficient coverage is achieved
* Produces a structured `research` output used downstream

Enabling `retrievals` streaming allows retrieved documents and search activity to be surfaced in the UI.

### Defining Tools for the Agent

The following configuration defines tools that the agent may use during research. Each tool wraps a standard step or subgraph and is exposed to the agent as a callable capability.

```yaml theme={null}
tools_config:
  - name: search_docs
    description: Search the datastore containing user-uploaded documents.
    step_config:
      type: SearchUnstructuredDataStep
      config:
        top_k: 50
        lexical_alpha: 0.1
        semantic_alpha: 0.9
        reranker: ctxl-rerank-v2-instruct-multilingual-FP8
        rerank_top_k: 12
        reranker_score_filter_threshold: 0.2
```

Bear in mind the following key points:

* Tools are defined inline using either `step_config` or `graph_config`
* Each tool encapsulates a retrieval or processing capability
* Tool inputs must use basic Python types
* Tool outputs are returned to the agent as structured retrieval results
* Exactly one of the following must be provided for each tool:
  `step_config`
  `graph_config`

### Configuring the Agent Loop

The following configuration controls how the agent reasons and how many turns it may take when performing research.

```yaml theme={null}
agent_config:
  agent_loop:
    num_turns: 10
    parallel_tool_calls: false
    model_name_or_path: vertex_ai/claude-opus-4-5@20251101
```

This configuration determines:

* The maximum number of reasoning and tool-use iterations
* Whether the agent can invoke multiple tools in parallel
* The model used for agent planning and decision-making

### Guiding Agent Behavior with Prompts<br />

The following prompts define *who the agent is* and *how it should conduct research*. These prompts guide internal reasoning and are not exposed to the user.

**Identity Guidelines**<br />
The identity guidelines describe the agent’s role and grounding expectations, ensuring it behaves as a factual, retrieval-augmented assistant.

```
identity_guidelines_prompt: |
            You are a retrieval-augmented assistant created by Contextual AI. You provide factual, grounded answers to user's questions by retrieving information via tools and then synthesizing a response based only on what you retrieved.
```

**Research Guidelines**<br />
The research guidelines define the agent’s strategy, including:

* Mandatory use of retrieval tools before answering
* A breadth-first, then depth-first research approach
* Explicit planning between retrieval phases
* Adaptive execution based on retrieved content
* Efficiency constraints without sacrificing completeness

These instructions ensure consistent and repeatable agent behavior across runs.

```
 research_guidelines_prompt: |
            You have access to the following tool:
            - `search_docs` — Search the document datastore. Returns SEARCH_RESULTS with CITE_ID for citation.
            
            You have access to the following data source:
            1. Document Datastore (Unstructured): 
                - Contains user-uploaded documents that have been parsed, extracted, and chunked for efficient retrieval.
                - Use the `search_docs` tool to query this datastore for relevant content, details, and information from the available documents.
            
            ## Research Strategy
            You MUST always explore unstructured datastore before answering. Do not skip the source.
            - Breadth, then depth strategy:
                1. INITIAL RETRIEVAL - FIRST (Mandatory):
                  - Documents: Use `search_docs` with your initial search terms.
                2. ANALYZE & PLAN: Review initial results and create a query plan:
                  - What information is still missing to fully answer the question?
                  - Create a specific plan: which queries to run next and in what order
                  - Identify dependencies: what do you need to find first before searching for related info?
                3. DEEP DIVE (Execute & Adapt): Execute your plan and adapt based on retrieved content:
                  - Run planned queries systematically
                  - Continue until you have a COMPLETE answer - don't stop early
            - EFFICIENCY: You have 10 turns. Be strategic:
                - Avoid redundant searches; prefer high-quality retrievals.
                - Batch related searches when possible
                - Don't repeat similar queries
                - Prioritize high-value retrievals first
                - But DO NOT sacrifice comprehensiveness for speed - gather ALL relevant information
```

### Generating the Final Response

The following step synthesizes a final user-facing response using the structured research output produced by the agent.
generate:

```yaml theme={null}
  type: GenerateFromResearchStep
  ui_stream_types:
    generation: true
```

This step:

* Consumes `message_history` and research
* Produces the final response returned by the graph
* Ensures the answer is grounded strictly in retrieved information
* Enabling generation streaming allows partial responses to be shown in the UI as they are produced.

### Controlling Response Style and Grounding

The response configuration enforces formatting, tone, and grounding constraints for the final output.

```yaml theme={null}
config:
  model_name_or_path: vertex_ai/claude-opus-4-5@20251101
```

Response guidelines typically enforce:

* Immediate answers with no preamble or meta-commentary
* Clear, concise Markdown formatting
* Explicit handling of missing or incomplete information
* A professional and neutral tone

This ensures consistent output quality and prevents internal reasoning or research details from leaking into the final response.

### End-to-End Data Flow

The overall execution flow of an agentic workflow is as follows:

```
inputs.query
  → CreateMessageHistoryStep
    → message_history
      → AgenticResearchStep
        → research
          → GenerateFromResearchStep
            → outputs.response
```

Each phase has a clearly defined responsibility, making the workflow easier to understand, debug, and extend.

### Design Principles

The agentic research pattern in Agent Composer is guided by a small set of core design principles. These principles ensure agent workflows remain understandable, reliable, and easy to operate as they grow in complexity.

* Separation of concerns: research and generation are handled by different steps
* Grounded responses: final answers are derived only from retrieved content
* Observability: retrievals and generation can be streamed independently
* Determinism: agent behavior is fully specified by configuration

***

## Creating New Steps

To add a new step:

1. Implement a `PipelineStep` subclass
2. Define `INPUTS`, `OUTPUTS`, and optional UI metadata
3. Register it in `registrations.py`
4. Add it to the step catalog for discoverability

## Running Graphs Programmatically

To run graphs programmatically, use the following Python code:

```python theme={null}
graph = ExecutableGraph.from_yaml(yaml_string)
graph.execute_graph({"query": "Hello"})
```

Inputs map to **inputs**, and outputs are returned as a `dict`.

***

## API Response

Agent Composer (AC) workflows are executed via `/query/acl`, with the following response fields returned:

* `outputs:` graph outputs (JSON-serializable)
* `workflow_trace:` executed nodes and durations
* `dynamic_agent_trace:` agent reasoning and tool usage (if applicable)

***

## Common Validation Errors

The following are common validation errors and how to fix them:

| Validation Error                     | Fix                                           |
| ------------------------------------ | --------------------------------------------- |
| Unsupplied node inputs               | Ensure every required input is mapped.        |
| Missing `__outputs__` node           | Explicitly map node outputs to graph outputs. |
| Multiple outputs without `ui_output` | Designate exactly one UI output.              |
| Non-serializable outputs             | Convert outputs to basic types before output. |

***

## Additional Resources

* [Agent Composer YAML Reference Catalog](/how-to-guides/ac-yaml-reference)
* [Agent Composer YAML Cheatsheet](/how-to-guides/ac-yaml-cheatsheet)
* [Agent Composer Quickstart Guide](/quickstarts/agent-composer)
* [Agent Composer GUI How-to Guide](/how-to-guides/agent-composer-gui)
