How DeepWiki DeepResearch Enables Multi-Turn Investigation: A Technical Deep Dive

DeepWiki's DeepResearch feature uses iteration-specific system prompts and conversation state tracking to enable structured multi-turn investigations that progressively build comprehensive answers across up to five conversational turns.

The DeepResearch capability in the AsyncFuncAI/deepwiki-open repository transforms single-turn chat interactions into structured, multi-turn investigations. By dynamically selecting system prompts based on conversation progress and maintaining persistent context through RAG memory, DeepResearch allows the assistant to iteratively explore complex topics until reaching a synthesized conclusion.

Detecting and Initiating a DeepResearch Session

The [DEEP RESEARCH] Marker

DeepResearch sessions begin when users include the [DEEP RESEARCH] tag in their query. This marker serves as a explicit signal to the chat handlers that the request requires multi-turn investigation rather than a standard single-response answer.

Flagging Logic in websocket_wiki.py and simple_chat.py

Both the WebSocket and HTTP endpoints implement identical detection logic. In api/websocket_wiki.py (lines 156-168), the server checks the last user message for the DeepResearch marker:


# From websocket_wiki.py lines 156-168

last_user_message = messages[-1]["content"]
is_deep_research = "[DEEP RESEARCH]" in last_user_message

if is_deep_research:
    # Strip the marker so the model sees only the raw query

    messages[-1]["content"] = last_user_message.replace("[DEEP RESEARCH]", "").strip()

The same pattern appears in api/simple_chat.py (lines 51-63), ensuring consistent behavior across transport protocols.

Tracking Research Iterations

Counting Assistant Messages

DeepResearch uses the count of existing assistant messages to determine the current iteration depth. The server calculates the next iteration number as assistant_message_count + 1, providing a zero-based index of how many research rounds have already occurred.

In api/websocket_wiki.py (lines 70-73):


# Calculate research iteration based on assistant message history

assistant_message_count = len([m for m in messages if m["role"] == "assistant"])
research_iteration = assistant_message_count + 1

The Research Iteration Counter

This counter serves dual purposes: it drives prompt selection (first, intermediate, or final) and gets injected into prompts via the {research_iteration} placeholder, allowing the model to understand its current position in the investigation sequence.

Managing Conversation Continuity

Handling "Continue Research" Commands

When users want to extend the investigation, they can send messages like "continue research". The server detects these continuation phrases and preserves the original research topic by extracting it from the first non-continuation user message in the history.

In api/websocket_wiki.py (lines 74-88):


# Handle "continue research" messages

if "continue research" in last_user_message.lower():
    # Find the original topic from the first non-continuation message

    for msg in messages:
        if msg["role"] == "user" and "continue research" not in msg["content"].lower():
            original_topic = msg["content"]
            break
    # Rewrite the last message to the original topic

    messages[-1]["content"] = original_topic

Topic Persistence Across Turns

This extraction mechanism ensures that the model always works with the original research subject, preventing topic drift when users issue continuation commands. The same logic appears in api/simple_chat.py (lines 69-83).

Dynamic System Prompts for Each Iteration

The multi-turn investigation relies on three distinct prompt templates defined in api/prompts.py, each optimized for a specific research phase.

First Iteration: Research Planning

The DEEP_RESEARCH_FIRST_ITERATION_PROMPT (lines 60-84) establishes the investigation framework. It instructs the model to create a structured research plan, identify key areas to explore, and set expectations for the investigation scope.

Intermediate Iterations: Building on Findings

The DEEP_RESEARCH_INTERMEDIATE_ITERATION_PROMPT (lines 22-45) guides the model to analyze previous findings, identify gaps in the current knowledge, and produce incremental updates. This template uses the {research_iteration} placeholder to label outputs as "Research Update 2", "Research Update 3", etc.

Final Iteration: Synthesizing Conclusions

The DEEP_RESEARCH_FINAL_ITERATION_PROMPT (lines 90-115) triggers when the iteration counter reaches the maximum depth. It demands a comprehensive "Final Conclusion" that synthesizes all previous research into a direct answer to the original question.

RAG Memory and Context Preservation

DeepResearch maintains conversation context through the request_rag.memory.add_dialog_turn mechanism. In api/websocket_wiki.py (lines 45-55), each user-assistant exchange is stored in the RAG memory:


# Store dialog turn in RAG memory for context retention

request_rag.memory.add_dialog_turn(
    user_message=last_user_message,
    assistant_message=assistant_response
)

This persistent memory allows the model to reference earlier findings without requiring the user to restate previous context, creating a coherent investigation thread across multiple turns.

Bounding Research Depth

To prevent infinite research loops, DeepResearch enforces a maximum of five iterations. When research_iteration >= 5, the system automatically selects the final iteration prompt, forcing the model to conclude the investigation regardless of user continuation requests.

This safeguard appears in api/websocket_wiki.py (lines 62-64):


# Enforce maximum research depth of 5 iterations

if research_iteration >= 5:
    prompt_template = DEEP_RESEARCH_FINAL_ITERATION_PROMPT

Summary

  • DeepResearch sessions are triggered by the [DEEP RESEARCH] marker in user messages, detected in both websocket_wiki.py and simple_chat.py.
  • Iteration tracking uses assistant message counts to determine research depth, driving the selection of first, intermediate, or final system prompts.
  • Topic persistence ensures continuity by extracting the original research subject when users send "continue research" commands.
  • Dynamic prompts in prompts.py provide structured guidance for each research phase, from initial planning through final synthesis.
  • RAG memory stores dialog turns to maintain context across multi-turn investigations without redundant repository searches.
  • Depth bounding limits research to five iterations, ensuring timely conclusion of investigations.

Frequently Asked Questions

How does DeepResearch detect when to start a multi-turn investigation?

DeepResearch detects the start of an investigation by scanning the last user message for the [DEEP RESEARCH] tag in both websocket_wiki.py (lines 156-168) and simple_chat.py (lines 51-63). When found, the server sets an internal flag, strips the marker from the message content, and initiates the iteration counting mechanism to track the research depth.

What happens when a user asks to "continue research"?

When the user sends a continuation message like "continue research", the server extracts the original research topic from the first non-continuation user message in the conversation history. This logic in websocket_wiki.py (lines 74-88) rewrites the current message to the original topic, ensuring the model continues investigating the same subject rather than treating the continuation as a new query.

How does DeepResearch prevent infinite research loops?

DeepResearch enforces a hard limit of five iterations by checking if research_iteration >= 5 in websocket_wiki.py (lines 62-64). Once this threshold is reached, the system automatically selects the DEEP_RESEARCH_FINAL_ITERATION_PROMPT from prompts.py, forcing the model to synthesize a final conclusion regardless of whether the user attempts to continue the research further.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →