Where Is the Vane Question Classification Logic Implemented?

Vane's question classification logic is implemented in the search agent at src/lib/agents/search/classifier.ts, which uses a detailed LLM prompt from src/lib/prompts/search/classifier.ts to categorize queries and determine whether to skip search, use specific search sources, or display widgets.

The ItzCrazyKns/Vane repository employs an intelligent query routing system that analyzes user intent before executing search operations. Understanding the exact location and mechanism of the Vane question classification logic is essential for developers customizing search behavior or debugging classification failures. This article examines the specific source files, function signatures, and data structures that power this classification system.

Core Implementation Files

The Vane question classification logic is distributed across two primary TypeScript modules that separate orchestration from prompt engineering.

The Classifier Module (src/lib/agents/search/classifier.ts)

This file exports the asynchronous classify function, which serves as the main entry point for query analysis. According to the Vane source code, this function constructs a structured request to the configured LLM, passing conversation history and the current user query to enable context-aware classification decisions.

The Classification Prompt (src/lib/prompts/search/classifier.ts)

The prompt file contains the classifierPrompt constant, which defines the AI's role, classification labels, and strict output format requirements. This prompt instructs the LLM to return a structured JSON object containing boolean flags for different search modes and widget triggers, ensuring deterministic downstream routing.

How the Classification Pipeline Works

The classification process follows a strict pipeline from the search agent through the LLM and back to the execution logic, with each component referencing specific source paths in the ItzCrazyKns/Vane codebase.

Invocation from the Search Agent

In src/lib/agents/search/index.ts, the search agent invokes the classifier before executing any retrieval operations. The agent passes the chat history, user query, enabled sources, and LLM configuration as a ClassifierInput object to determine the appropriate action.

import { classify } from './classifier';

// Inside SearchAgent.searchAsync …
const classification = await classify({
  chatHistory: input.chatHistory,
  enabledSources: input.config.sources,
  query: input.followUp,
  llm: input.config.llm,
});

The classify Function Implementation

The classify function in src/lib/agents/search/classifier.ts formats the input into a message array and invokes the LLM's structured object generation capability. It combines the system prompt with user-specific context, including formatted conversation history wrapped in XML-like tags.

export const classify = async (input: ClassifierInput) => {
  const output = await input.llm.generateObject<typeof schema>({
    messages: [
      { role: 'system', content: classifierPrompt },
      {
        role: 'user',
        content: `<conversation_history>\n${formatChatHistoryAsString(
          input.chatHistory,
        )}\n</conversation_history>\n<user_query>\n${input.query}\n</user_query>`,
      },
    ],
    schema,
  });

  return output;
};

LLM Prompt Structure and Schema

The prompt defined in src/lib/prompts/search/classifier.ts establishes the AI's role as an advanced system designed to analyze user queries. It specifies the exact JSON output format required, including boolean fields for skipSearch, personalSearch, academicSearch, discussionSearch, and widget triggers such as showWeatherWidget, showStockWidget, and showCalculationWidget.

export const classifierPrompt = `
<role>
Assistant is an advanced AI system designed to analyze the user query …
</role>
...
<output_format>
{
  "classification": {
    "skipSearch": boolean,
    "personalSearch": boolean,
    "academicSearch": boolean,
    "discussionSearch": boolean,
    "showWeatherWidget": boolean,
    "showStockWidget": boolean,
    "showCalculationWidget": boolean
  },
  "standaloneFollowUp": string
}
</output_format>
`;

Classification Output and Routing

The classification result consumed by src/lib/agents/search/index.ts determines the search agent's subsequent behavior through structured boolean flags. When skipSearch evaluates to true, the agent bypasses retrieval entirely and generates a direct response. Specific search type flags trigger their respective pipelines—personal search, academic search, or discussion search—while widget flags invoke specialized UI components for weather, stocks, or calculations. The standaloneFollowUp field provides a query reformulation optimized for search engine consumption, independent of conversational context.

Summary

  • Vane question classification logic resides primarily in src/lib/agents/search/classifier.ts, which implements the asynchronous classify function.
  • The classification prompt lives in src/lib/prompts/search/classifier.ts and defines the LLM's system instructions, role, and required JSON output schema.
  • The search agent at src/lib/agents/search/index.ts consumes classification results to route queries to appropriate search sources or widgets.
  • The system uses structured JSON output with boolean flags to determine whether to skip search, use specific academic/personal/discussion sources, or display specialized widgets.
  • Classification incorporates conversation history via formatChatHistoryAsString for context-aware query understanding and generates a standalone follow-up query for search optimization.

Frequently Asked Questions

What file contains the main classification function in Vane?

The main classification function is exported from src/lib/agents/search/classifier.ts. This module contains the classify async function that orchestrates LLM calls using generateObject to categorize user queries based on conversation context and current input parameters.

How does Vane determine which search source to use?

Vane uses boolean flags returned by the classifier—specifically personalSearch, academicSearch, and discussionSearch—to determine which search verticals to query. The search agent in src/lib/agents/search/index.ts reads these flags from the classification result and activates only the corresponding search pipelines while respecting the enabledSources configuration.

Where is the classification prompt defined in the Vane codebase?

The classification prompt is defined in src/lib/prompts/search/classifier.ts as the classifierPrompt constant. This file contains the complete system instructions, role definition, classification rules, and the required JSON output format including all widget and search type boolean fields that guide the LLM's reasoning process.

Can the Vane classifier skip search entirely?

Yes. When the LLM returns skipSearch: true in the classification object, the search agent bypasses all retrieval operations and generates a direct response using only the LLM's parametric knowledge. This optimization prevents unnecessary API calls for queries requiring simple conversational responses, calculations, or generic advice.

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 →