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

# Respond node

> Assemble a final or intermediate response, either by filling a template or by generating structured output with an LLM

## Purpose

The **Respond node** produces a response value and stores it in the variable store for later steps (or for the [End node](/workflows/overview#end-node-output) to return). It runs in one of two modes:

* **Template mode** — pure string interpolation with `{{path}}` placeholders. No LLM is called, so it is instant, deterministic, and free. Use it to format data you already have into a message.
* **DSPy mode** — an LLM generates typed, structured output against an `output_schema`. Use it when you need the model to summarize, rewrite, or compose prose from upstream data.

Where the [Agent node](/workflows/agent-node) gives an LLM tools, knowledge bases, and multi-step reasoning, the Respond node is a single, focused generation (or no generation at all). Reach for Respond when you just need to shape the final answer; reach for Agent when the step needs to reason, call tools, or decide.

<Note>
  A Respond node requires **either** a `template` **or** an `output_schema`. Supplying neither is a configuration error. If a `template` is present, the node runs in template mode and no LLM is called, even if other DSPy fields are set.
</Note>

## How it works

<Steps>
  <Step title="Workflow reaches the Respond node">
    Execution arrives with the outputs of previous steps available in the variable store, plus the execution input under `input`.
  </Step>

  <Step title="Mode is selected">
    If `template` is set, the node runs in template mode. Otherwise it runs in DSPy mode against the `output_schema`.
  </Step>

  <Step title="Template mode: placeholders are filled">
    Each `{{path}}` in the template is resolved against the variable store. Unresolved paths are left in place as literal `{{path}}` text rather than failing the node.
  </Step>

  <Step title="DSPy mode: the LLM generates output">
    Input fields are resolved from their sources, an agent's persona instructions are optionally applied, and the configured DSPy module (`typed_predict` or `chain_of_thought`) generates output matching the schema.
  </Step>

  <Step title="Result is stored">
    The result is written to the variable store under `output_variable` (default `response`), where downstream nodes and the End node can read it.
  </Step>
</Steps>

## Configuration

<Tabs>
  <Tab title="Template mode">
    Set `template` to a string with `{{path}}` placeholders. Paths resolve against the variable store, and the execution input is available under `input`.

    ```json theme={null}
    {
      "id": "format",
      "type": "respond",
      "config": {
        "template": "Results for '{{input.query}}':\n{{search.results}}",
        "output_variable": "formatted_response"
      }
    }
    ```

    | Field             | Required | Description                                                                                                                                     |
    | ----------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
    | `template`        | Yes      | String with `{{path}}` placeholders. Dotted paths (including hyphenated activity ids like `agent-mp2oqv6n`) resolve against the variable store. |
    | `output_variable` | No       | Variable name to store the rendered string. Default `response`.                                                                                 |
    | `name`            | No       | Display label for the node on the canvas.                                                                                                       |

    <Note>
      Template mode never calls an LLM. A placeholder that doesn't resolve is kept verbatim as `{{path}}` in the output, so a typo shows up in the text rather than crashing the node.
    </Note>
  </Tab>

  <Tab title="DSPy mode">
    Omit `template` and provide an `output_schema`. The node calls an LLM to generate structured output. `llm_config_id` is required for this mode.

    ```json theme={null}
    {
      "id": "summarize",
      "type": "respond",
      "config": {
        "input_fields": {
          "data": { "source": "search.results", "description": "Data to summarize" }
        },
        "output_schema": {
          "properties": {
            "summary": { "type": "string", "description": "Brief summary" }
          }
        },
        "module_type": "chain_of_thought",
        "llm_config_id": "llm-uuid",
        "output_variable": "summary_result"
      }
    }
    ```

    | Field             | Required | Description                                                                                                                                      |
    | ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
    | `output_schema`   | Yes      | JSON Schema (`properties`) describing the structured output the LLM must produce.                                                                |
    | `llm_config_id`   | Yes      | UUID of the LLM config to run the generation.                                                                                                    |
    | `input_fields`    | No       | Map of input names to their sources. Each entry uses `source` (a path like `search.results` or `input.query`), a direct `value`, or a `default`. |
    | `module_type`     | No       | `typed_predict` (default) for direct structured prediction, or `chain_of_thought` to let the model reason before answering.                      |
    | `agent_id`        | No       | An agent whose `persona.instructions` are applied as the generation instructions.                                                                |
    | `output_variable` | No       | Variable name to store the result. Default `response`.                                                                                           |
    | `name`            | No       | Display label for the node on the canvas.                                                                                                        |

    <Tip>
      When the schema has a single string output field, the node stores the raw string under `output_variable` (not a one-key wrapper object), so downstream `{{respond.response}}` references get clean text instead of a JSON blob.
    </Tip>
  </Tab>
</Tabs>

### Input field sources (DSPy mode)

Each entry in `input_fields` resolves in one of three ways:

* **`source`** — a dotted path. `input.<field>` reads from the execution input; `variables.<name>` (or a bare activity path like `search.results`) reads from the variable store.
* **`value`** — a literal value injected directly.
* **`default`** — a fallback value used when neither `source` nor `value` is set.

## Respond vs Agent

<Columns cols={2}>
  <Card title="Use a Respond node when">
    * You only need to **format** data you already have (template mode).
    * You need **one** structured LLM generation (summary, rewrite, classification) with no tools.
    * You want a deterministic, no-LLM final message.
    * You want to shape the value the End node returns.
  </Card>

  <Card title="Use an Agent node when">
    * The step needs to **call tools** or MCP servers.
    * The step needs **knowledge-base retrieval** (RAG).
    * The step requires **multi-step reasoning** or decisions.
    * You want guardrails, a full persona, and agent-level configuration.
  </Card>
</Columns>

## Use cases

### Format a final message without an LLM

**Scenario:** A search step produced results; you just need to present them.

```json theme={null}
{
  "id": "_respond",
  "type": "respond",
  "config": {
    "template": "Here is what I found for '{{input.query}}':\n\n{{search.results}}",
    "output_variable": "response"
  }
}
```

### Summarize upstream data with structured output

**Scenario:** Condense a long extraction into a short, typed summary before the End node returns it.

```
Workflow:
  1. Extract document text (Agent)
  2. Respond node (DSPy): summarize into { summary }
  3. End: return { response: respond.summary }
```

```json theme={null}
{
  "id": "summarize",
  "type": "respond",
  "config": {
    "input_fields": {
      "data": { "source": "extract.text", "description": "Extracted document text" }
    },
    "output_schema": {
      "properties": {
        "summary": { "type": "string", "description": "Two-sentence summary" }
      }
    },
    "module_type": "chain_of_thought",
    "llm_config_id": "{{project_default_llm}}"
  }
}
```

## Best practices

<AccordionGroup>
  <Accordion title="Prefer template mode when you don't need generation">
    If every value already exists in the variable store, template mode formats it instantly with no LLM cost and fully deterministic output.
  </Accordion>

  <Accordion title="Give output fields clear descriptions">
    In DSPy mode, the `description` on each schema property guides the model. Precise descriptions produce more reliable structured output.
  </Accordion>

  <Accordion title="Reach for an Agent when tools or knowledge are involved">
    The Respond node has no tools and no knowledge-base retrieval. If the step needs either, use an [Agent node](/workflows/agent-node) instead.
  </Accordion>

  <Accordion title="Name the output variable for downstream use">
    Set `output_variable` to something descriptive so later nodes and the End node can reference it clearly, e.g. `{{summarize.summary_result}}`.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Agent node" icon="robot" href="/workflows/agent-node">
    Use a full agent when the step needs tools, knowledge, or reasoning
  </Card>

  <Card title="Workflow overview" icon="diagram-project" href="/workflows/overview">
    See how the End node returns the final output
  </Card>

  <Card title="Memory system" icon="database" href="/workflows/memory">
    Understand the variable store that templates and inputs read from
  </Card>

  <Card title="Condition node" icon="code-branch" href="/workflows/condition-node">
    Branch on a response before returning it
  </Card>
</CardGroup>
