# What Is the Role of the ReportAgent in Generating Simulation Predictions?

> Discover the ReportAgent's crucial role in simulation predictions. Learn how this engine orchestrates data into narrative reports via planning, writing, and finalization.

- Repository: [BaiFu/mirofish](https://github.com/666ghj/mirofish)
- Tags: deep-dive
- Published: 2026-02-23

---

**The ReportAgent serves as the core orchestration engine that transforms raw simulation data into structured, narrative-style prediction reports through a systematic three-stage process of planning, evidence-driven writing, and finalization.**

In the **mirofish** repository, the ReportAgent is responsible for converting simulation requirements and graph statistics into trustworthy, evidence-based predictions. According to the source code in [`backend/app/services/report_agent.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/services/report_agent.py), this agent implements a ReACT (Reason-Act-Observe-Reflect) architecture that ensures every generated claim is grounded in retrieved simulation data. By coordinating with **ZepToolsService** and multiple retrieval tools, the ReportAgent produces fully reproducible Markdown reports complete with structured logging for traceability.

## ReportAgent Architecture and Core Responsibilities

The ReportAgent operates as the central intelligence layer between raw simulation outputs and human-readable prediction reports. It manages the entire lifecycle of report generation through three distinct operational stages that ensure both narrative coherence and factual accuracy.

### Stage 1: Planning and Outline Creation

During the planning phase, the ReportAgent analyzes simulation requirements and graph statistics to draft a comprehensive report structure. The `plan_outline()` method (approximately lines 30-48 in [`backend/app/services/report_agent.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/services/report_agent.py)) gathers context via `ZepToolsService.get_simulation_context()` and invokes the LLM using `PLAN_SYSTEM_PROMPT` and `PLAN_USER_PROMPT_TEMPLATE` to generate a structured outline containing titles, summaries, and section headers.

This initial stage ensures the final report aligns precisely with the user's prediction goals, such as forecasting campus epidemic spread trends or analyzing network diffusion patterns.

### Stage 2: Evidence-Driven Section Generation

For each section defined in the outline, the agent executes a ReACT loop through the `_generate_section_react()` method (lines 124-210). This implementation follows the Reason-Act-Observe-Reflect pattern where the agent **thinks** about required information, **acts** by invoking retrieval tools, and **observes** the results before reflecting and continuing.

The loop guarantees at least three tool calls per section, querying the simulation knowledge base through four specialized tools: `insight_forge`, `panorama_search`, `quick_search`, and `interview_agents`. Tool execution is delegated through `_execute_tool()` (lines 65-115), which forwards calls to the `ZepToolsService` defined in [`backend/app/services/zep_tools.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/services/zep_tools.py).

### Stage 3: Finalization and Persistence

In the final stage, the `generate_report()` method (approximately lines 210-260) assembles all generated sections into a complete Markdown document. This process creates structured JSONL logs via `ReportLogger` and plain-text console logs through `ReportConsoleLogger`, ensuring full traceability of the generation process.

The method returns a `Report` model that encapsulates the final content, timestamps, and metadata, which is then persisted by `ReportManager` for long-term storage and retrieval.

## Technical Implementation Deep Dive

### ReACT Loop Mechanics in `_generate_section_react()`

The `_generate_section_react()` implementation ensures evidence-based writing by mandating multiple retrieval cycles before content finalization. During each iteration, the agent evaluates whether sufficient simulation data has been collected to support the narrative claim, preventing hallucination and ensuring grounded predictions.

This architectural choice guarantees that every statement in the generated report traces back to specific simulation facts stored in the Zep knowledge graph.

### Tool Integration via `ZepToolsService`

The ReportAgent relies on `ZepToolsService` to interface with the underlying simulation database. The four retrieval tools serve distinct functions: `insight_forge` generates deep analytical insights, `panorama_search` provides broad context scans, `quick_search` retrieves specific facts, and `interview_agents` queries other agent perspectives within the simulation.

These tools are invoked through the `_execute_tool()` wrapper, which handles error management and response formatting before returning structured data to the ReACT loop.

## Working with the ReportAgent: Code Examples

### Basic Report Generation

The following example demonstrates instantiating the ReportAgent and generating a prediction report for campus epidemic forecasting:

```python
from backend.app.services.report_agent import ReportAgent

graph_id = "mirofish_12345"
simulation_id = "sim_20240223"
simulation_requirement = "预测2025年校园疫情传播趋势"

agent = ReportAgent(
    graph_id=graph_id,
    simulation_id=simulation_id,
    simulation_requirement=simulation_requirement,
)

def progress(stage, percent, message):
    print(f"[{stage}] {percent}% – {message}")

report = agent.generate_report(progress_callback=progress, report_id="report_demo")
print(report.markdown_content)   # Full Markdown report

```

### Flask API Integration

In production environments, the ReportAgent is typically invoked through the Flask API endpoint defined in [`backend/app/api/report.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/api/report.py):

```python

# Simplified excerpt from backend/app/api/report.py

agent = ReportAgent(graph_id, simulation_id, simulation_requirement)
report = agent.generate_report(progress_callback=callback, report_id=report_id)
ReportManager.save_report(report)   # Persists the report and its logs

```

This pattern enables asynchronous report generation with real-time progress tracking suitable for frontend visualization.

## Integration with the Mirofish Ecosystem

The ReportAgent functions as a critical component within the broader mirofish architecture, interfacing with multiple subsystems to deliver end-to-end prediction reporting. The agent consumes data from the Zep knowledge graph through [`backend/app/services/zep_tools.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/services/zep_tools.py), persists task states via [`backend/app/models/task.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/models/task.py), and provides real-time updates consumed by [`frontend/src/components/Step5Interaction.vue`](https://github.com/666ghj/mirofish/blob/main/frontend/src/components/Step5Interaction.vue) for progress visualization.

By combining LLM-driven narrative generation with rigorous evidence retrieval, the ReportAgent bridges the gap between complex simulation outputs and actionable predictive insights.

## Summary

- The **ReportAgent** orchestrates three distinct stages: planning outlines via `plan_outline()`, generating sections through `_generate_section_react()`, and finalizing reports with `generate_report()`.
- It implements a **ReACT loop** (lines 124-210) that mandates multiple tool invocations per section, ensuring predictions are grounded in simulation data rather than hallucinated.
- Four specialized tools—`insight_forge`, `panorama_search`, `quick_search`, and `interview_agents`—retrieve evidence from the Zep knowledge base during content generation.
- Complete **traceability** is maintained through structured JSONL logging (`ReportLogger`) and console logging (`ReportConsoleLogger`), with final persistence handled by `ReportManager`.
- The primary implementation resides in [`backend/app/services/report_agent.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/services/report_agent.py), with API endpoints in [`backend/app/api/report.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/api/report.py) and frontend visualization in [`frontend/src/components/Step5Interaction.vue`](https://github.com/666ghj/mirofish/blob/main/frontend/src/components/Step5Interaction.vue).

## Frequently Asked Questions

### What is the primary function of the ReportAgent in mirofish?

The ReportAgent functions as the core prediction report engine that transforms raw simulation statistics and graph data into structured Markdown narratives. It ensures all predictions are evidence-based by requiring tool-retrieved simulation data for every claim generated during the ReACT loop process.

### How does the ReportAgent ensure predictions are grounded in simulation data?

The agent enforces a strict ReACT (Reason-Act-Observe-Reflect) pattern in `_generate_section_react()` that requires at least three tool calls per section. By mandating retrieval from `insight_forge`, `panorama_search`, `quick_search`, or `interview_agents` before content finalization, the architecture guarantees that every narrative claim traces back to specific simulation facts stored in the Zep knowledge graph.

### What specific tools does the ReportAgent use during content generation?

The ReportAgent utilizes four retrieval tools provided by `ZepToolsService`: `insight_forge` for deep analytical insights, `panorama_search` for broad context scans, `quick_search` for targeted fact retrieval, and `interview_agents` for querying perspectives from other simulation agents. These tools are invoked through the `_execute_tool()` method (lines 65-115) during the ReACT loop.

### Where is the ReportAgent instantiated in the production codebase?

In production deployments, the ReportAgent is instantiated within the Flask API endpoint defined in [`backend/app/api/report.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/api/report.py). This endpoint creates the agent with specific `graph_id`, `simulation_id`, and `simulation_requirement` parameters, then calls `generate_report()` to launch the asynchronous generation process tracked via [`backend/app/models/task.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/models/task.py).