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 bothwebsocket_wiki.pyandsimple_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.pyprovide 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →