Workflow History & Continuous Execution

Build workflows that reference previous runs across multiple executions using workflow history.

Before running the examples, create and activate a virtual environment:

uv pip install agno openai sqlalchemy
export OPENAI_API_KEY="your-api-key"
v2.1.4

Workflow History enables your Agno workflows to remember and reference previous conversations, transforming isolated executions into continuous, context-aware interactions.

Instead of starting fresh each time, with Workflow History you can:

  • Build on previous interactions - Reference the context of past interactions
  • Avoid repetitive questions - Avoid requesting previously provided information
  • Maintain context continuity - Create a conversational experience
  • Learn from patterns - Analyze historical data to make better decisions

This feature is different from add_history_to_context. It adds prior completed workflow input/output pairs to selected steps. These pairs are distinct from an individual agent's message history and from preceding step output in the current run.

The fragments below reuse this setup:

from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.workflow import Step, Workflow
from agno.workflow.types import StepInput, StepOutput

db = SqliteDb(db_file="tmp/history_workflow.db")
research_agent = Agent(name="Research", instructions="Summarize the supplied topic.")
analysis_agent = Agent(name="Analysis", instructions="Analyze the preceding summary.")
writing_agent = Agent(name="Writer", instructions="Write a short answer from the supplied context.")
content_agent = writing_agent
research_step = Step("Research", agent=research_agent)
analysis_step = Step("Analysis", agent=analysis_agent)
writing_step = Step("Writing", agent=writing_agent)

How It Works

When workflow history is enabled, the last three completed runs' input/final-output pairs are injected into agent/team step inputs by default:

<workflow_history_context>
[Workflow Run-1]
User input: Create content about AI in healthcare
Workflow output: # AI in Healthcare: Transforming Patient Care...

[Workflow Run-2]
User input: Make it more family-focused
Workflow output: # AI in Family Healthcare: A Parent's Guide...

</workflow_history_context>

Your current input goes here...

Along with this, in using Steps with custom functions, you can access this history in the following ways:

  1. As a formatted context string as shown above
  2. In a structured format as well for more control
[
    ("<workflow input from run 1>", "<workflow output from run 1>"),
    ("<workflow input from run 2>", "<workflow output from run 2>"),
]

A database is required to use Workflow history. Runs across different executions will be persisted there.

Example:

def custom_function(step_input: StepInput) -> StepOutput:
    # Option 1: Structured data for analysis
    history_tuples = step_input.get_workflow_history(num_runs=3)
    for user_input, workflow_output in history_tuples:
        ...  # Process each conversation turn

    # Option 2: Formatted context for agents
    context_string = step_input.get_workflow_history_context(num_runs=3)

    return StepOutput(content="Analysis complete")

You can use these helper functions to access the history:

  • step_input.get_workflow_history(num_runs=3)
  • step_input.get_workflow_history_context(num_runs=3)

Refer to StepInput reference for more details.

Control Levels

You can be specific about which Steps to add the history to:

Workflow-Level History

Add workflow history to all steps in the workflow:

workflow = Workflow(
    db=db,
    steps=[research_step, analysis_step, writing_step],
    add_workflow_history_to_steps=True  # All steps get history
)

Step-Level History

Add workflow history to specific steps only:

Step(
    name="Content Creator",
    agent=content_agent,
    add_workflow_history=True  # Only this step gets history
)

You can also put add_workflow_history=False to disable history for a specific step.

Precedence Logic

Step-level settings always take precedence over workflow-level settings:

workflow = Workflow(
    db=db,
    steps=[
        Step("Research", agent=research_agent),                              # None → inherits workflow setting
        Step("Analysis", agent=analysis_agent, add_workflow_history=False),  # False → overrides workflow
        Step("Writing", agent=writing_agent, add_workflow_history=True),     # True → overrides workflow
    ],
    add_workflow_history_to_steps=True  # Default for all steps
)

History Length Control

By default, each step receives the last 3 runs (num_history_runs=3). Keep this limit small to avoid bloating the LLM context window.

Set num_history_runs on each agent/team Step when you need a different window. In the current implementation, the Step default of three overrides a larger Workflow(num_history_runs=...) value.

workflow = Workflow(
    db=db,
    add_workflow_history_to_steps=True,
    steps=[
        Step("Research", agent=research_agent, num_history_runs=5),
        Step("Analysis", agent=analysis_agent, num_history_runs=3),
        Step("Writing", agent=writing_agent, num_history_runs=5),
    ],
)
workflow.print_response("Explain workflow history", session_id="history-demo")
workflow.print_response("Give a shorter explanation", session_id="history-demo")

For a custom function, the num_runs argument on StepInput's history helpers controls its window independently.

Developer Resources