Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
294 changes: 73 additions & 221 deletions src/tools/extract_antv_topic.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
/**
* AntV Intelligent Assistant Preprocessing Tool
*
* 处理所有与 AntV 可视化库相关的用户查询,智能识别、解析并结构化用户需求。
* 支持自动识别库类型、提取技术主题关键词、判断用户意图,并为后续 query_antv_document 工具准备结构化信息。
* AntV Topic Extraction Tool - Preprocesses user queries for AntV libraries
*/

import { z } from 'zod';
import type { AntVLibrary } from '../types';
import { logger } from '../utils';
Expand Down Expand Up @@ -51,251 +47,117 @@ interface ExtractAntVTopicArgs {
}

function generateExtractionPrompt(args: ExtractAntVTopicArgs): string {
const libraryContext = args.library
? getLibraryConfig(args.library)
: undefined;
return generateUnifiedPrompt(args.query, args.maxTopics, libraryContext);
}

function generateUnifiedPrompt(
query: string,
maxTopics: number,
libraryContext?: { id: AntVLibrary; name: string },
): string {
const isLibrarySpecified = !!libraryContext;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

原来的分发函数太复杂了,直接在prompt里用三元表达式做处理

const allLibraries = Object.values(ANTV_LIBRARY_META);
const libraryDeterminationSection = isLibrarySpecified
? generateLibrarySpecifiedSection(libraryContext)
: generateLibraryDetectionSection(allLibraries);
const extractionRulesSection = generateExtractionRulesSection(
maxTopics,
libraryContext,
);
const outputFormatSection = generateOutputFormatSection();
const examplesSection = generateExamplesSection();
return `# AntV ${isLibrarySpecified ? 'Topic and Intent Extraction' : 'Smart Library Detection and Topic Extraction'} Task

## Task Objective
${
isLibrarySpecified
? `Extract the most relevant technical topic phrases and user intent from user queries for ${libraryContext.name} documentation retrieval.`
: `1. First: Detect and recommend the most suitable AntV library based on query intent and installed dependencies
2. Second: Extract relevant technical topics and user intent for the determined library`
}

## User Query

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

提示次变化挺多的,要不详细描述一下去掉了哪些

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我看出来 generateExamplesSection 没有了

\`\`\`
${query}
\`\`\`

${libraryDeterminationSection}

${extractionRulesSection}

## Output Format

${outputFormatSection}

## Examples

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

因为有format,感觉example不是很必要,反而会增加token消耗,所以去掉了


${examplesSection}

Now please begin ${isLibrarySpecified ? 'extraction' : 'the detection and extraction process'}:
const { query, library, maxTopics } = args;

## Important Notice
**MANDATORY NEXT STEP**: After completing this task, immediately call the \`query_antv_document\` tool with the extracted parameters.

**Requirements:**
- Always use extracted library, topic, intent parameters with \`query_antv_document\` tool
- Never skip \`query_antv_document\` tool call and answer directly
- For complex tasks: pass subTasks parameter; for simple tasks: use basic parameters`;
}

function generateLibrarySpecifiedSection(libraryContext: {
id: AntVLibrary;
name: string;
}): string {
return `## Phase 1: Library Context
**Target Library**: ${libraryContext.name} (${libraryContext.id})`;
}

function generateLibraryDetectionSection(
allLibraries: Array<{ id: AntVLibrary; name: string; description: string }>,
): string {
// 动态生成库映射列表
// Generate library mappings
const libraryMappings = Object.values(ANTV_LIBRARY_META)
.map((lib) => ` - \`@antv/${lib.id}\` → ${lib.name}`)
.map((lib) => ` - **${lib.name} (${lib.id})**: ${lib.description}`)
.join('\n');

return `## Phase 1: Library Detection and Recommendation

**Your first task is to determine the most suitable AntV library for this query.**
// Get library-specific context if specified
const libraryContext = library

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prompt里避免重复引入library name和config,直接合并了

? {
name: getLibraryConfig(library).name,
keywords: getLibraryKeywords(library),
}
: null;

### Step 1.1: Project Dependency Scan
Scan the user's current project for installed AntV dependencies:
1. **Check package.json**: Look for AntV-related dependencies in both \`dependencies\` and \`devDependencies\`
2. **Look for patterns**:
${libraryMappings}
const libraryTerminology = libraryContext
? libraryContext.keywords
: 'Use the terminology and components specific to the determined target library';

### Step 1.2: Smart Library Recommendation
Based on query content and detected dependencies, recommend the most suitable library:
return `# AntV Query Analysis & Topic Extraction

**Library Selection Rules (Priority Order):**
1. **Query Intent Match**: Select library that best matches the technical requirements:
${allLibraries
.map((lib) => `- **${lib.name} (${lib.id})**: ${lib.description}`)
.join('\n ')}
## User Query
**Query**: ${query}
**Max Topics**: ${maxTopics}
${library ? `**Specified Library**: ${getLibraryConfig(library).name} (${library})` : '**Library**: Auto-detect'}

2. **Installed Dependency Priority**: If multiple libraries match the intent, prioritize installed ones
3. **Best Practice Guidance**: Consider the most commonly used library for the specific use case
## Task Instructions

**Output the recommended library and reason before proceeding to Phase 2.**`;
}
### Phase 1: Library Detection ${library ? '(Skipped - Library Specified)' : ''}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对于需要推断library的,直接填入Auto-detect,让大模型去推断,mcp里不写过多冗余的逻辑

${
library
? `Using specified library: **${getLibraryConfig(library).name} (${library})**`
: `**Determine the most suitable AntV library:**

function generateExtractionRulesSection(
maxTopics: number,
libraryContext?: { id: AntVLibrary; name: string },

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

推断 library 的冗余提示词

): string {
const libraryTerminology = libraryContext
? getLibraryKeywords(libraryContext.id)
: 'Use the terminology and components specific to the determined target library';
const librarySpecificPriority = libraryContext
? `${libraryContext.name} specific component concepts and APIs`
: 'Target library specific component concepts and APIs';
return `## Phase 2: Topic Extraction and Intent Recognition
Available Libraries:
${libraryMappings}

Once you have the target library (either specified or determined), proceed with:
**Selection Priority:**
1. Match query intent with library purpose
2. Check for existing project dependencies
3. Consider common use cases for the query type`
}

### 2.1: Complex Task Detection
Determine whether the user query is a complex task. Characteristics of complex tasks:
- Contains multiple technical concepts or functional points
- Requires multiple steps to complete
- Involves multiple chart types or multiple functions
- Has clear workflow or combination requirements
### Phase 2: Topic Extraction & Analysis

### 2.2: Topic Phrase Extraction
- **Source Limitation**: Extract only from user query content, do not add concepts not present in the query
- **CRITICAL: All topics MUST be in English** - Use official AntV English terminology from: ${
libraryContext
? getLibraryKeywords(libraryContext.id)
: 'Use the terminology and components specific to the determined target library'
}
- 翻译和提取时,务必优先使用上方列出的官方组件英文名称,保持与官方文档一致,避免自创或误译,保持技术准确性
- **Quantity Requirement**: Maximum ${maxTopics} items, can be fewer than this number
- **Format Requirements**:
- Extract meaningful phrase combinations (1-4 words)
- Avoid single words or overly long sentences
- Ensure diversity between terms, avoid repetition
- **MANDATORY**: Output only English technical terms for documentation search
- **Components, Concepts, Terminology**: ${libraryTerminology}
- **Priority**:
1. ${librarySpecificPriority}
2. Chart types and visualization concepts
3. Interaction, animation effects, data processing and configuration
**Extract up to ${maxTopics} key technical topics covering ALL aspects mentioned:**
- Extract only from user query content, no additional concepts
- Use official AntV English terminology${libraryContext ? `: ${libraryContext.keywords}` : ''}
- Format as meaningful phrases (1-4 words), output in English only
- **Cover these technical aspects in priority order**:
Comment thread
tangying1027 marked this conversation as resolved.
1. Chart types and core components
2. Visual styling (colors, thickness, backgrounds, opacity)
3. Interactions (hover, click, tooltip, zoom)
4. Configurations (data processing, scales, axis, animations)

### 2.3: User Intent Recognition
**Determine User Intent:**
Based on the tone and content of the query, select the most matching intent:
- **learn**: Learning and understanding (e.g., what is, how to understand, introduce)
- **implement**: Implementing functionality (e.g., how to create, how to implement, code examples)
- **solve**: Solving problems (e.g., errors, not working, fixing issues)

### 2.4: Complex Task Decomposition
If determined to be a complex task, decompose into 2-4 subtasks, each subtask should:
**Assess Task Complexity:**
Determine if the query is complex based on:
- Extracted topics exceed 5
Comment thread
tangying1027 marked this conversation as resolved.
- Involves more than 2 components or features
- Other cases where the query appears complex based on overall assessment (e.g., multi-step processes, combinations of features)


If complex, decompose into 2-4 subtasks, each subtask should:
- Focus on a specific technical point or functionality
- Be able to independently obtain answers through documentation queries
- Be arranged in logical order (basic → advanced)
- Subtask topics must be clear, concise, and follow the format requirements above

**Note**: For complex tasks, provide the decomposed subtask list to the query_antv_document tool for one-time processing.`;
}
### Phase 3: Output Format

function generateOutputFormatSection(): string {
return `### Simple Task Output Format:
**For Simple Tasks:**
\`\`\`json
{
"topic": "actually extracted topic1, topic2, topic3",
"library": "detected_or_specified_library",
"topic": "topic1, topic2, topic3",
"intent": "learn|implement|solve",
"library": "the target library (either specified or determined)",
"isComplexTask": false
}
\`\`\`

### Complex Task Output Format:
**For Complex Tasks:**
\`\`\`json
{
"topic": "summary of all related topics",
"intent": "overall intent",
"library": "the target library (either specified or determined)",
"library": "detected_or_specified_library",
"topic": "overall_topic_summary",
"intent": "overall_intent",
"isComplexTask": true,
"subTasks": [
{
"query": "specific question for subtask 1",
"topic": "topic for subtask 1",
"intent": "intent for subtask 1"
"query": "specific_subtask_question_1",
"topic": "subtask_topic_1"
},
{
"query": "specific question for subtask 2",
"topic": "topic for subtask 2",
"intent": "intent for subtask 2"
"query": "specific_subtask_question_2",
"topic": "subtask_topic_2"
}
]
}
\`\`\``;
}

function generateExamplesSection(): string {
return `**Example 1 - Simple Task (English Query)**
Query: "What is G2?"
Output:
\`\`\`json
{
"topic": "G2 introduction",
"intent": "learn",
"library": "g2",
"isComplexTask": false
}
\`\`\`

**Example 2 - Simple Task (Chinese Query)**
Query: "如何修改G2图表的颜色?"
Output:
\`\`\`json
{
"topic": "chart color, styling",
"intent": "implement",
"library": "g2",
"isComplexTask": false
}
\`\`\`
**Analyze the query and provide the structured output above.**

**Example 3 - Complex Task**
Query: "How to create an animated bar chart with hover interaction in G2?"
Output:
\`\`\`json
{
"topic": "animated bar chart, chart animation, hover interaction, mouse events",
"intent": "implement",
"library": "g2",
"isComplexTask": true,
"subTasks": [
{
"query": "How to create a basic bar chart in G2?",
"topic": "bar chart, chart creation",
"intent": "implement"
},
{
"query": "How to add animation effects to G2 charts?",
"topic": "chart animation, animation effects",
"intent": "implement"
},
{
"query": "How to add hover interaction to G2 charts?",
"topic": "hover interaction, mouse events",
"intent": "implement"
}
]
}
\`\`\``;
## Important Notice
**MANDATORY NEXT STEP**: After completing this task, immediately call the \`query_antv_document\` tool with the extracted parameters.
`;
}

export const ExtractAntVTopicTool = {
Expand All @@ -321,8 +183,8 @@ Key features:
const startTime = Date.now();
try {
const extractionPrompt = generateExtractionPrompt(args);
const maxTopics = args.maxTopics;
const processingTime = Date.now() - startTime;

return {
content: [
{
Expand All @@ -333,8 +195,8 @@ Key features:
_meta: {
topic: '', // Will be filled by LLM
intent: '', // Will be filled by LLM
library: args.library || 'g2',
maxTopics,
library: args.library || 'auto-detect',
maxTopics: args.maxTopics,
promptGenerated: true,
next_tools: ['query_antv_document'],
isComplexTask: false, // Will be determined and filled by LLM
Expand All @@ -344,18 +206,8 @@ Key features:
};
} catch (error) {
logger.error('Failed to generate extraction prompt:', error);
// Use safe fallbacks since validation might have failed
const fallbackLibrary =
args.library && Object.keys(ANTV_LIBRARY_META).includes(args.library)
? args.library
: 'g2';
const fallbackMaxTopics =
typeof args.maxTopics === 'number' &&
args.maxTopics >= 3 &&
args.maxTopics <= 8
? args.maxTopics
: 5;
const processingTime = Date.now() - startTime;

return {
content: [
{
Expand All @@ -369,8 +221,8 @@ Key features:
_meta: {
topic: '',
intent: '',
library: fallbackLibrary,
maxTopics: fallbackMaxTopics,
library: args.library || 'auto-detect',
maxTopics: args.maxTopics,
promptGenerated: false,
next_tools: ['query_antv_document'],
isComplexTask: false,
Expand Down
Loading