# How to Customize Research Brief Generation from User Messages in Open Deep Research

> Customize research brief generation in Open Deep Research by modifying prompts, swapping them at runtime, adjusting model settings, or post-processing output. Learn how to tailor brief creation.

- Repository: [LangChain/open_deep_research](https://github.com/langchain-ai/open_deep_research)
- Tags: how-to-guide
- Published: 2026-07-23

---

**You can customize the research brief generation in the Open Deep Research agent by modifying the prompt template in [`src/open_deep_research/prompts.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/prompts.py), swapping prompts at runtime within the `write_research_brief` node, adjusting model configuration settings, or post-processing the output before it enters the graph state.**

The Open Deep Research agent converts conversational user messages into structured research directives through a specialized LangGraph workflow. When you need to tailor how the system interprets user intent, enforces formatting constraints, or selects models for this transformation, you must customize the research brief generation pipeline that transforms `state["messages"]` into the `state["research_brief"]` field.

## Understanding the Research Brief Generation Flow

The brief generation occurs in the **`write_research_brief`** node defined in [`src/open_deep_research/deep_researcher.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/deep_researcher.py). According to the langchain-ai/open_deep_research source code, the node executes four distinct operations:

1. **Collects message history** from `state["messages"]` to establish conversational context.
2. **Formats a prompt** using `transform_messages_into_research_topic_prompt` (located in [`src/open_deep_research/prompts.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/prompts.py)), which instructs the LLM to distill the chat into a concrete research question.
3. **Invokes the research model** (`configurable_model`) with a structured output schema called `ResearchQuestion`, expecting a single field named `research_brief`.
4. **Persists the result** into the graph state at `state["research_brief"]`, making it available to the supervisor node for downstream research orchestration.

Because the brief derives entirely from a prompt template and model invocation, you have four distinct extension points for customization.

## Modifying the Prompt Template

The most direct way to customize research brief generation is to edit the **`transform_messages_into_research_topic_prompt`** variable in [`src/open_deep_research/prompts.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/prompts.py). This string template accepts `{messages}` and `{date}` placeholders and dictates tone, format, and constraints.

To enforce a specific output structure—such as requiring Markdown headings or bullet lists—modify the template definition:

```python

# src/open_deep_research/prompts.py

transform_messages_into_research_topic_prompt = """You will be given a set of messages that have been exchanged so far between yourself and the user.
Your job is to translate these messages into a concise research brief that will guide the subsequent research.

**Requirements**
- Begin the brief with a level-2 Markdown heading: `## Research Brief`

- Limit the brief to *no more than 150 words*.
- Preserve any user-specified constraints (e.g., preferred sources, language).

The messages that have been exchanged so far between yourself and the user are:
<Messages>
{messages}
</Messages>

Today's date is {date}.

Return **only** the brief text, without any additional explanation.
"""

```

After restarting the agent, the `write_research_brief` node automatically uses this updated template, producing briefs that follow your new formatting rules.

## Swapping the Prompt at Runtime

For dynamic customization without modifying source files, override the prompt within the **`write_research_brief`** function in [`src/open_deep_research/deep_researcher.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/deep_researcher.py). This approach lets you load templates from external files or environment variables based on runtime conditions.

```python

# src/open_deep_research/deep_researcher.py

async def write_research_brief(state, config):
    # ... existing setup code ...

    
    # Load a custom template from a file or environment variable

    custom_prompt = Path("custom_prompt.txt").read_text()
    prompt_content = custom_prompt.format(
        messages=get_buffer_string(state.get("messages", [])),
        date=get_today_str()
    )
    
    # Invoke model with custom prompt

    response = await research_model.ainvoke([
        SystemMessage(content=prompt_content)
    ])
    return {"research_brief": response.research_brief}

```

This method is ideal for multi-tenant deployments where different users require distinct brief formats.

## Adjusting Model Configuration

You can change which model generates the brief—or its generation parameters—via **[`src/open_deep_research/configuration.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/configuration.py)**. The `Configuration` class exposes fields that the `write_research_brief` node uses to initialize the `configurable_model`.

```python

# src/open_deep_research/configuration.py

class Configuration(BaseSettings):
    research_model: str = "gpt-4o-mini"   # Change to Claude, Gemini, etc.

    research_model_max_tokens: int = 1024
    research_model_temperature: float = 0.2

```

Adjusting these values alters the brief's creativity, length, and reasoning characteristics without changing the prompt logic.

## Post-Processing the Output

To apply additional transformations—such as adding metadata tags, trimming whitespace, or injecting citations—modify the `write_research_brief` function after the model invocation but before returning the state update:

```python

# src/open_deep_research/deep_researcher.py

async def write_research_brief(state, config):
    # ... prompt setup and invocation ...

    response = await research_model.ainvoke([...])
    
    # Post-process the generated brief

    processed_brief = response.research_brief.strip()
    processed_brief = f"[Generated on {get_today_str()}]\n\n{processed_brief}"
    
    return {"research_brief": processed_brief}

```

This technique allows you to enforce length constraints programmatically or append system metadata that the raw LLM output might omit.

## Key Files for Customization

| File | Role | Key Component |
|------|------|---------------|
| [`src/open_deep_research/prompts.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/prompts.py) | Stores LLM prompt templates | `transform_messages_into_research_topic_prompt` |
| [`src/open_deep_research/deep_researcher.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/deep_researcher.py) | Implements LangGraph nodes | `write_research_brief` function |
| [`src/open_deep_research/state.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/state.py) | Defines graph state schema | `research_brief` field |
| [`src/open_deep_research/configuration.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/configuration.py) | Runtime model settings | `Configuration` class fields |

## Summary

- The research brief is generated in the `write_research_brief` node within [`src/open_deep_research/deep_researcher.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/deep_researcher.py) using the `transform_messages_into_research_topic_prompt` template.
- Edit [`src/open_deep_research/prompts.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/prompts.py) to permanently change formatting instructions, length constraints, or tone requirements.
- Override prompts at runtime in `write_research_brief` to support dynamic or user-specific brief formats.
- Adjust model selection and parameters in [`src/open_deep_research/configuration.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/configuration.py) to change generation quality without code modifications.
- Post-process the `response.research_brief` output before returning it to the state to inject metadata or enforce programmatic constraints.

## Frequently Asked Questions

### Where exactly is the research brief generated in the codebase?

The brief is generated in the **`write_research_brief`** async function inside [`src/open_deep_research/deep_researcher.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/deep_researcher.py). This LangGraph node extracts messages from the state, formats them using the prompt template, and invokes the configured research model with the `ResearchQuestion` structured output schema.

### What is the structure of the research brief output?

The brief is stored as a string in `state["research_brief"]`. The LLM is constrained by the `ResearchQuestion` Pydantic model (referenced in [`deep_researcher.py`](https://github.com/langchain-ai/open_deep_research/blob/main/deep_researcher.py)), which expects a single field named `research_brief` containing the distilled research directive. You can enforce specific formats—such as Markdown headings or bullet lists—by editing the prompt template instructions.

### Can I use a different model specifically for brief generation?

Yes. The model used for brief generation is controlled by the **`research_model`** field in [`src/open_deep_research/configuration.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/configuration.py). Changing this configuration value switches the LLM used in the `write_research_brief` node. You can also adjust `research_model_max_tokens` and temperature settings to fine-tune output characteristics.

### How do I access the generated brief in downstream research nodes?

The brief is automatically persisted to the graph state at the key **`research_brief`** (defined in [`src/open_deep_research/state.py`](https://github.com/langchain-ai/open_deep_research/blob/main/src/open_deep_research/state.py)). Subsequent nodes, including the supervisor, access this value via `state["research_brief"]` to guide query generation, source selection, and synthesis operations.