How to Implement Intent Analysis for Query Preprocessing in OpenViking
OpenViking performs intent-driven hierarchical retrieval by analyzing user queries through the IntentAnalyzer class, which assembles session context, calls a VLM, and produces a structured QueryPlan to drive downstream retrieval.
The volcengine/OpenViking repository implements a sophisticated retrieval system that preprocesses user queries through intent analysis before executing hierarchical searches. By understanding whether a user seeks memories, resources, or skills, the system optimizes retrieval paths through typed query decomposition. This article explains how to implement and customize this intent analysis pipeline using the actual source code from the OpenViking project.
Understanding the IntentAnalyzer Architecture
The IntentAnalyzer class in openviking/retrieve/intent_analyzer.py serves as the central component for query preprocessing. It transforms raw user input into a structured retrieval plan by coordinating context assembly, LLM interaction, and response parsing.
Core Responsibilities
The analyzer executes a four-step pipeline:
- Context Collection – Aggregates session compression summaries, recent message history, current user queries, optional
ContextTypeconstraints, and target directory abstracts. - LLM Invocation – Dispatches the assembled prompt to the configured vision language model via
vlm.get_completion_async. - Response Parsing – Extracts JSON payloads using
parse_json_from_responsefromopenviking_cli/utils/llm.py, handling thequerieslist andreasoningfields. - QueryPlan Generation – Instantiates
TypedQueryobjects for each entry in the JSON array, wrapping them in aQueryPlanwith session context and raw reasoning.
Implementing Intent Analysis in Your Application
Direct Usage of IntentAnalyzer
To implement intent analysis independently of the high-level file system API, instantiate the analyzer and provide session context:
from openviking.retrieve.intent_analyzer import IntentAnalyzer
from openviking_cli.retrieve.types import ContextType
# Configure session data
compression_summary = "User is discussing project X architecture."
recent_messages = [
{"role": "user", "content": "How do I store vectors?"},
{"role": "assistant", "content": "You can use VikingDB..."},
]
current_query = "Show me examples of hierarchical retrieval."
# Optional constraints
target_context_type = ContextType.RESOURCE
target_abstract = "Resource folder for retrieval utilities."
# Initialize analyzer
analyzer = IntentAnalyzer(max_recent_messages=5)
# Generate query plan
query_plan = await analyzer.analyze(
compression_summary=compression_summary,
messages=recent_messages,
current_message=current_query,
context_type=target_context_type,
target_abstract=target_abstract,
)
# Process typed queries
for typed_q in query_plan.queries:
print(f"[{typed_q.context_type}] ({typed_q.priority}) {typed_q.query}")
print(f" Intent: {typed_q.intent}")
This implementation calls _build_context_prompt internally to assemble the prompt, then parses the LLM's JSON response into TypedQuery objects containing query, context_type, intent, priority, and optional reasoning fields.
Integration with VikingFS.search
In production deployments, intent analysis triggers automatically within the high-level storage API. The search method in openviking/storage/viking_fs.py (approximately lines 640-700) implements the following logic:
# Inside VikingFS.search method
if session_summary or recent_messages:
analyzer = IntentAnalyzer(max_recent_messages=5)
query_plan = await analyzer.analyze(
compression_summary=session_summary or "",
messages=recent_messages or [],
current_message=query,
context_type=target_context_type,
target_abstract=target_abstract,
)
typed_queries = query_plan.queries
# Apply directory constraints if specified
if target_uri:
for tq in typed_queries:
tq.target_directories = [target_uri]
else:
# Fallback without intent analysis
typed_queries = [
TypedQuery(
query=query,
context_type=target_context_type,
intent="",
priority=3
)
]
# typed_queries now drives HierarchicalRetriever
This integration demonstrates session-aware preprocessing: the analyzer only executes when session context exists, otherwise the system falls back to raw query processing.
Customizing the Intent Analysis Prompt
The IntentAnalyzer delegates prompt construction to openviking/prompts.py using the template key retrieval.intent_analysis. The _build_context_prompt method (lines 20-27 in intent_analyzer.py) injects the following variables:
compression_summary– Session overview or "None"recent_messages– Formatted message history ([role]: content)current_message– The active user querycontext_type– Optional constraint ("memory","resource", or"skill")target_abstract– Directory description for targeted searches
To customize behavior, modify the prompt template in openviking/prompts.py or override _build_context_prompt in a subclass. The LLM must return JSON matching the schema expected by parse_json_from_response in openviking_cli/utils/llm.py.
Summary
- IntentAnalyzer in
openviking/retrieve/intent_analyzer.pyprovides the core preprocessing logic for OpenViking's retrieval system. - The analyzer assembles session context, invokes the VLM via
vlm.get_completion_async, and parses structured JSON intoTypedQueryobjects. - VikingFS.search automatically triggers intent analysis when session summaries or recent messages are present, falling back to raw queries otherwise.
- The prompt template
retrieval.intent_analysiscontrols LLM behavior and expects variables for compression summaries, message history, and target context types.
Frequently Asked Questions
How does OpenViking handle queries without session context?
When no session_summary or recent_messages are provided to VikingFS.search, the system bypasses IntentAnalyzer entirely. It creates a single TypedQuery object using the raw user query string, sets the priority to 3, and passes this directly to the HierarchicalRetriever.
What is the difference between TypedQuery and QueryPlan?
A TypedQuery represents a single decomposed search intent with fields for query text, context_type (memory/resource/skill), intent description, `
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 →