🔥 DeepEval 4.0 just got released. Read the announcement.

Custom Templates

Customize the prompts used to simulate user turns by passing a template= to default_simulation_node and feeding the returned node into simulation_graph.

API

from deepeval.simulator import default_simulation_node

default_simulation_node(template=MyTemplate)
ArgumentDescription
templateA subclass of SimulationTemplate overriding simulate_first_user_turn() and/or simulate_user_turn(). Validated eagerly — invalid templates raise TypeError at construction time. When omitted, the built-in SimulationTemplate is used.
terminal, max_visits, nameSame as SimulationNode — see Simulation Graph for full reference.

A custom template must:

  • Inherit from SimulationTemplate.
  • Override simulate_first_user_turn(golden, language) to change how the first user message is generated.
  • Override simulate_user_turn(golden, turns, language) to change how follow-up user messages are generated.

Both methods must return a prompt string that elicits a JSON response with one key: simulated_input.

Example

from deepeval.simulator import (
    ConversationSimulator,
    SimulationTemplate,
    default_simulation_node,
)

class FormalUserTemplate(SimulationTemplate):
    @staticmethod
    def simulate_first_user_turn(golden, language):
        return f"""
        Pretend you are a formal enterprise buyer.
        Start a conversation in {language} for this scenario:
        {golden.scenario}

        Return JSON with one key: simulated_input.
        """

    @staticmethod
    def simulate_user_turn(golden, turns, language):
        return f"""
        Continue the conversation as a formal enterprise buyer.
        Keep the tone concise, professional, and procurement-oriented.

        Scenario: {golden.scenario}
        Conversation so far: {turns}

        Return JSON with one key: simulated_input.
        """

simulator = ConversationSimulator(
    model_callback=model_callback,
    simulation_graph=default_simulation_node(template=FormalUserTemplate),
)

Common Use Cases

User Style

Use a custom template when simulated users should speak in a specific voice, such as formal buyers, frustrated customers, clinicians, students, or non-technical users.

Domain Framing

Use a custom template when the generated user turns should reflect domain-specific behavior, vocabulary, or constraints that the default simulator prompt does not emphasize.

Conversation Pressure

Use a custom template when you want simulated users to be more adversarial, more confused, more concise, or more persistent than the default role-play behavior.

Mixing with a Simulation Graph

You can also embed default_simulation_node(template=...) as one node inside a larger simulation graph — useful when you want a custom template for free-form exploration on some branches and deterministic, scripted nodes on others.

from deepeval.simulator import SimulationNode, default_simulation_node

scripted_opener = SimulationNode(
    action=lambda: "Hi, I need help with a refund.",
    name="opener",
)
scripted_opener.add_node(
    default_simulation_node(template=FormalUserTemplate),
    when="The assistant asked a clarifying question",
)

FAQs

On this page