# How WriterAgent Generates Formatted Academic Papers from Modeling Results in MathModelAgent

> Discover how WriterAgent uses LLM conversations and tool integrations to automatically generate formatted academic papers from modeling results within MathModelAgent.

- Repository: [Sanjin/mathmodelagent](https://github.com/jihe520/mathmodelagent)
- Tags: how-to-guide
- Published: 2026-03-04

---

**The WriterAgent transforms raw modeling outputs into competition-ready academic manuscripts by orchestrating a multi-turn LLM conversation that automatically invokes literature search tools, injects citations, and enforces markdown formatting rules defined in system prompts.**

The `WriterAgent` in the [jihe520/mathmodelagent](https://github.com/jihe520/mathmodelagent) repository serves as the final automated author in a multi-agent mathematical modeling pipeline. After the Modeler and Coder agents produce computational results, this specialized component synthesizes the findings into structured, citation-rich academic papers suitable for mathematical modeling competitions.

## Agent Initialization and System Prompt Construction

The agent's behavior is established during instantiation in `WriterAgent.__init__` (lines 19-36 of [`backend/app/core/agents/writer_agent.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/core/agents/writer_agent.py)). The constructor accepts a `task_id`, an LLM instance, a formatting enum defaulting to `FormatOutPut.Markdown`, and an optional `OpenAlexScholar` wrapper for literature retrieval.

Crucially, the constructor generates a specialized system prompt by calling `get_writer_prompt(format_output)` from [`backend/app/core/prompts.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/core/prompts.py) (lines 37-88). This prompt encodes the writer role definition, citation formatting rules, and markdown structure requirements that constrain the LLM's output format.

## The Execution Pipeline: From Raw Data to Formatted Manuscript

The `WriterAgent.run` method (lines 53-142) implements a sophisticated multi-turn conversation loop that handles dynamic literature retrieval and citation integration.

### Step 1: Prompt Enrichment with Visual Assets

When image file names are provided via the `available_images` parameter, the agent automatically appends markdown-style image URL references to the user prompt (lines 59-66). This allows the LLM to reference figures and charts generated by upstream modeling agents.

### Step 2: Initial LLM Invocation with Tool Access

The first LLM call (lines 70-78) passes the enriched history to `self.model.chat` with `tools=writer_tools` and `tool_choice="auto"`. The `writer_tools` schema defined in [`backend/app/core/functions.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/core/functions.py) exposes the `search_papers` function to the LLM, enabling autonomous literature requests when the draft requires theoretical backing.

### Step 3: Automated Literature Retrieval via OpenAlex

When the LLM response contains `tool_calls` requesting `search_papers` (lines 84-122), the agent executes a closed-loop retrieval sequence:

1. Publishes a status message via `redis_manager` for front-end progress tracking
2. Extracts the search query from the tool call arguments
3. Invokes `self.scholar.search_papers(query)` through the `OpenAlexScholar` wrapper in [`backend/app/tools/openalex_scholar.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/tools/openalex_scholar.py)
4. Formats the returned bibliography using `self.scholar.papers_to_str`
5. Appends a tool message containing the formatted citations back into the chat history

### Step 4: Citation Integration and Final Output Generation

Following literature injection (lines 124-137), a second LLM call incorporates the retrieved papers into the draft. The final content is stored in `response_content`, wrapped in a `WriterResponse` object (lines 138-142), and returned to the caller with an optional `footnotes` list reserved for custom annotations.

## Practical Implementation Example

The following demonstrates instantiation and execution:

```python
from app.core.llm.llm import LLM
from app.core.agents.writer_agent import WriterAgent
from app.tools.openalex_scholar import OpenAlexScholar

# Configure dependencies

llm = LLM(...)
scholar = OpenAlexScholar()

# Initialize agent

writer = WriterAgent(
    task_id="task-1234",
    model=llm,
    format_output=FormatOutPut.Markdown,
    scholar=scholar,
)

# Generate paper with image references

paper = await writer.run(
    prompt="请基于模型结果撰写完整的竞赛论文，包括理论背景、模型描述和结果分析。",
    available_images=["20250420-173744-9f87792c/1_分布.png"],
)
print(paper.response_content)  # Markdown-formatted academic paper

```

## Optional Summarization Capabilities

Beyond full manuscript generation, the `WriterAgent.summarize` method (lines 43-58) provides concise synthesis of the writing exchange using the same chat-based architecture, enabling executive summaries of complex modeling workflows.

## Summary

- The **WriterAgent** in [`backend/app/core/agents/writer_agent.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/core/agents/writer_agent.py) serves as the automated authorial component in the mathmodelagent architecture.
- **System prompt construction** via `get_writer_prompt` establishes markdown formatting and citation rules during initialization (lines 19-36).
- **Multi-turn conversation loops** handle dynamic literature requests through the `search_papers` tool integration (lines 84-122).
- **OpenAlexScholar** integration in [`backend/app/tools/openalex_scholar.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/tools/openalex_scholar.py) provides real-time academic paper retrieval without direct API coupling.
- **WriterResponse** objects encapsulate the final formatted content and metadata for downstream consumption.
- **Redis status updates** enable real-time front-end progress tracking during literature searches.

## Frequently Asked Questions

### What output format does WriterAgent generate by default?

By default, the agent outputs **Markdown** format as specified by the `FormatOutPut.Markdown` enum passed during initialization. The system prompt generated by `get_writer_prompt` in [`backend/app/core/prompts.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/core/prompts.py) enforces specific markdown structure rules for academic paper sections, including headers, equations, and citation blocks.

### How does WriterAgent handle citations without direct API calls?

The agent delegates literature searches to the **OpenAlexScholar** wrapper class in [`backend/app/tools/openalex_scholar.py`](https://github.com/jihe520/mathmodelagent/blob/main/backend/app/tools/openalex_scholar.py). When the LLM requests citations via the `search_papers` tool, the agent calls `self.scholar.search_papers()` and formats results using `papers_to_str()`, then injects these as tool messages into the conversation history for the LLM to reference.

### Can WriterAgent include figures and charts in the generated paper?

Yes. By passing file paths through the `available_images` parameter in `WriterAgent.run`, the agent appends markdown-style image references to the prompt (lines 59-66), enabling the LLM to reference visual assets generated by upstream modeling components such as distribution plots or result charts.

### What happens if the LLM does not request literature searches?

If the LLM generates content without invoking the `search_papers` tool, the agent skips the retrieval loop and returns the draft immediately. The `tool_choice="auto"` setting in the chat call allows the LLM to determine whether theoretical citations are necessary based on the prompt content and subject matter.