Skip to main content
Glama

Open Search MCP

by flyanima
MIT License
2
  • Apple
  • Linux
chain-of-thought-executor.ts19.3 kB
/** * Chain of Thought Executor - 思维链执行器 * 执行分解后的研究查询,管理思维链推理过程 */ import { EventEmitter } from 'events'; import { DecomposedQuery, ExecutionPlan, ResearchQuery } from './query-decomposer.js'; import { Logger } from '../utils/logger.js'; export interface ThoughtChain { id: string; parentQueryId: string; steps: ThoughtStep[]; currentStep: number; status: ChainStatus; startedAt: string; completedAt?: string; totalExecutionTime: number; confidence: number; metadata: ChainMetadata; } export interface ThoughtStep { id: string; stepNumber: number; query: DecomposedQuery; reasoning: string; searchResults: SearchResult[]; analysis: StepAnalysis; conclusions: string[]; confidence: number; executionTime: number; status: StepStatus; dependencies: string[]; nextSteps: string[]; } export interface StepAnalysis { relevanceScore: number; qualityScore: number; completenessScore: number; consistencyScore: number; noveltyScore: number; evidenceStrength: number; biasDetection: BiasAnalysis; factualAccuracy: number; } export interface BiasAnalysis { detectedBiases: BiasType[]; confidenceInDetection: number; mitigationSuggestions: string[]; } export interface ChainMetadata { createdAt: string; domain: string; complexity: string; totalSteps: number; parallelSteps: number; criticalPath: string[]; estimatedTime: number; } export interface SearchResult { id: string; title: string; url: string; snippet: string; source: string; relevanceScore: number; qualityScore: number; timestamp: string; metadata: any; } export interface ExecutionResult { chainId: string; originalQuery: ResearchQuery; thoughtChain: ThoughtChain; finalConclusions: Conclusion[]; synthesizedAnswer: string; confidence: number; evidenceQuality: number; completeness: number; executionMetrics: ExecutionMetrics; } export interface Conclusion { id: string; statement: string; confidence: number; supportingEvidence: Evidence[]; contradictingEvidence: Evidence[]; certaintyLevel: CertaintyLevel; scope: string; } export interface Evidence { source: string; content: string; relevanceScore: number; credibilityScore: number; recency: number; type: EvidenceType; } export interface ExecutionMetrics { totalTime: number; searchTime: number; analysisTime: number; synthesisTime: number; queriesExecuted: number; resultsProcessed: number; averageRelevance: number; averageQuality: number; } export type ChainStatus = 'pending' | 'running' | 'completed' | 'failed' | 'paused'; export type StepStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped'; export type BiasType = 'confirmation' | 'selection' | 'temporal' | 'source' | 'cultural' | 'cognitive'; export type CertaintyLevel = 'very_low' | 'low' | 'moderate' | 'high' | 'very_high'; export type EvidenceType = 'primary' | 'secondary' | 'expert_opinion' | 'statistical' | 'anecdotal'; export class ChainOfThoughtExecutor extends EventEmitter { private logger: Logger; private activeChains: Map<string, ThoughtChain> = new Map(); private searchEngine: any; // 将与搜索引擎集成 private analysisEngine: any; // 将与分析引擎集成 constructor() { super(); this.logger = new Logger('ChainOfThoughtExecutor'); } /** * 执行思维链 */ async executeChain( originalQuery: ResearchQuery, decomposedQueries: DecomposedQuery[], executionPlan: ExecutionPlan ): Promise<ExecutionResult> { const chainId = this.generateChainId(); this.logger.info(`Starting chain of thought execution for query: ${originalQuery.originalQuery}`); try { // 1. 初始化思维链 const thoughtChain = this.initializeChain(chainId, originalQuery, decomposedQueries, executionPlan); this.activeChains.set(chainId, thoughtChain); // 2. 执行思维链步骤 await this.executeSteps(thoughtChain, executionPlan); // 3. 分析和综合结果 const conclusions = await this.analyzeAndSynthesize(thoughtChain); // 4. 生成最终答案 const synthesizedAnswer = await this.generateFinalAnswer(thoughtChain, conclusions); // 5. 计算执行指标 const executionMetrics = this.calculateExecutionMetrics(thoughtChain); const result: ExecutionResult = { chainId, originalQuery, thoughtChain, finalConclusions: conclusions, synthesizedAnswer, confidence: this.calculateOverallConfidence(thoughtChain, conclusions), evidenceQuality: this.calculateEvidenceQuality(thoughtChain), completeness: this.calculateCompleteness(thoughtChain, originalQuery), executionMetrics }; this.logger.info(`Chain of thought execution completed for ${chainId}`); this.emit('chainCompleted', result); return result; } catch (error) { this.logger.error(`Chain of thought execution failed for ${chainId}:`, error); this.emit('chainFailed', chainId, error); throw error; } finally { this.activeChains.delete(chainId); } } /** * 初始化思维链 */ private initializeChain( chainId: string, originalQuery: ResearchQuery, decomposedQueries: DecomposedQuery[], executionPlan: ExecutionPlan ): ThoughtChain { const steps: ThoughtStep[] = decomposedQueries.map((query, index) => ({ id: `step-${index + 1}`, stepNumber: index + 1, query, reasoning: this.generateInitialReasoning(query), searchResults: [], analysis: this.initializeStepAnalysis(), conclusions: [], confidence: 0, executionTime: 0, status: 'pending', dependencies: query.dependencies, nextSteps: [] })); const thoughtChain: ThoughtChain = { id: chainId, parentQueryId: originalQuery.id, steps, currentStep: 0, status: 'pending', startedAt: new Date().toISOString(), totalExecutionTime: 0, confidence: 0, metadata: { createdAt: new Date().toISOString(), domain: originalQuery.domain, complexity: originalQuery.complexity, totalSteps: steps.length, parallelSteps: executionPlan.parallelGroups.flat().length, criticalPath: executionPlan.criticalPath, estimatedTime: executionPlan.phases.reduce((sum, phase) => sum + phase.estimatedTime, 0) } }; return thoughtChain; } /** * 执行思维链步骤 */ private async executeSteps(thoughtChain: ThoughtChain, executionPlan: ExecutionPlan): Promise<void> { thoughtChain.status = 'running'; const startTime = Date.now(); for (const phase of executionPlan.phases) { this.logger.info(`Executing phase: ${phase.name}`); if (phase.canRunInParallel) { await this.executeStepsInParallel(thoughtChain, phase.subQueryIds); } else { await this.executeStepsSequentially(thoughtChain, phase.subQueryIds); } } thoughtChain.status = 'completed'; thoughtChain.completedAt = new Date().toISOString(); thoughtChain.totalExecutionTime = Date.now() - startTime; } /** * 并行执行步骤 */ private async executeStepsInParallel(thoughtChain: ThoughtChain, stepIds: string[]): Promise<void> { const steps = thoughtChain.steps.filter(step => stepIds.includes(step.query.id)); const promises = steps.map(step => this.executeStep(step)); await Promise.allSettled(promises); } /** * 顺序执行步骤 */ private async executeStepsSequentially(thoughtChain: ThoughtChain, stepIds: string[]): Promise<void> { const steps = thoughtChain.steps.filter(step => stepIds.includes(step.query.id)); for (const step of steps) { await this.executeStep(step); } } /** * 执行单个步骤 */ private async executeStep(step: ThoughtStep): Promise<void> { const startTime = Date.now(); step.status = 'running'; try { this.logger.debug(`Executing step ${step.stepNumber}: ${step.query.subQuery}`); // 1. 执行搜索 step.searchResults = await this.performSearch(step.query); // 2. 分析结果 step.analysis = await this.analyzeStepResults(step); // 3. 生成推理和结论 step.reasoning = await this.generateStepReasoning(step); step.conclusions = await this.generateStepConclusions(step); // 4. 计算置信度 step.confidence = this.calculateStepConfidence(step); step.status = 'completed'; step.executionTime = Date.now() - startTime; this.logger.debug(`Step ${step.stepNumber} completed with confidence ${step.confidence}`); } catch (error) { step.status = 'failed'; step.executionTime = Date.now() - startTime; this.logger.error(`Step ${step.stepNumber} failed:`, error); throw error; } } /** * 执行搜索 */ private async performSearch(query: DecomposedQuery): Promise<SearchResult[]> { // 这里将集成实际的搜索引擎 // 暂时返回模拟结果 const mockResults: SearchResult[] = [ { id: `result-${Date.now()}-1`, title: `Search result for: ${query.subQuery}`, url: 'https://example.com/result1', snippet: `This is a relevant snippet for the query: ${query.subQuery}`, source: 'example.com', relevanceScore: 0.85, qualityScore: 0.8, timestamp: new Date().toISOString(), metadata: { searchStrategy: query.searchStrategy } }, { id: `result-${Date.now()}-2`, title: `Additional information about: ${query.subQuery}`, url: 'https://example.com/result2', snippet: `More detailed information regarding: ${query.subQuery}`, source: 'example.com', relevanceScore: 0.75, qualityScore: 0.85, timestamp: new Date().toISOString(), metadata: { searchStrategy: query.searchStrategy } } ]; return mockResults; } /** * 分析步骤结果 */ private async analyzeStepResults(step: ThoughtStep): Promise<StepAnalysis> { const results = step.searchResults; const analysis: StepAnalysis = { relevanceScore: this.calculateAverageRelevance(results), qualityScore: this.calculateAverageQuality(results), completenessScore: this.assessCompleteness(results, step.query), consistencyScore: this.assessConsistency(results), noveltyScore: this.assessNovelty(results), evidenceStrength: this.assessEvidenceStrength(results), biasDetection: await this.detectBias(results), factualAccuracy: this.assessFactualAccuracy(results) }; return analysis; } /** * 生成步骤推理 */ private async generateStepReasoning(step: ThoughtStep): Promise<string> { const query = step.query; const results = step.searchResults; const analysis = step.analysis; let reasoning = `For the query "${query.subQuery}" (${query.type} type):\n\n`; reasoning += `Found ${results.length} relevant results with average relevance of ${(analysis.relevanceScore * 100).toFixed(1)}%.\n`; reasoning += `Quality assessment shows ${(analysis.qualityScore * 100).toFixed(1)}% quality score.\n`; if (analysis.biasDetection.detectedBiases.length > 0) { reasoning += `Detected potential biases: ${analysis.biasDetection.detectedBiases.join(', ')}.\n`; } reasoning += `Evidence strength is ${(analysis.evidenceStrength * 100).toFixed(1)}% with factual accuracy of ${(analysis.factualAccuracy * 100).toFixed(1)}%.\n`; return reasoning; } /** * 生成步骤结论 */ private async generateStepConclusions(step: ThoughtStep): Promise<string[]> { const conclusions: string[] = []; // 基于搜索结果生成结论 if (step.searchResults.length > 0) { const topResult = step.searchResults[0]; conclusions.push(`Based on search results, ${step.query.subQuery.toLowerCase()} shows ${topResult.snippet}`); } // 基于分析生成结论 if (step.analysis.relevanceScore > 0.8) { conclusions.push(`High relevance found for this aspect of the research question`); } if (step.analysis.evidenceStrength > 0.7) { conclusions.push(`Strong evidence supports the findings for this query component`); } return conclusions; } /** * 分析和综合结果 */ private async analyzeAndSynthesize(thoughtChain: ThoughtChain): Promise<Conclusion[]> { const conclusions: Conclusion[] = []; // 综合所有步骤的结论 const allStepConclusions = thoughtChain.steps.flatMap(step => step.conclusions); const allEvidence = thoughtChain.steps.flatMap(step => step.searchResults.map(result => ({ source: result.source, content: result.snippet, relevanceScore: result.relevanceScore, credibilityScore: result.qualityScore, recency: this.calculateRecency(result.timestamp), type: 'secondary' as EvidenceType })) ); // 生成主要结论 const mainConclusion: Conclusion = { id: `conclusion-main-${Date.now()}`, statement: this.synthesizeMainConclusion(allStepConclusions), confidence: this.calculateOverallConfidence(thoughtChain, []), supportingEvidence: allEvidence.filter(e => e.relevanceScore > 0.7), contradictingEvidence: [], certaintyLevel: this.determineCertaintyLevel(thoughtChain), scope: 'comprehensive' }; conclusions.push(mainConclusion); return conclusions; } /** * 生成最终答案 */ private async generateFinalAnswer(thoughtChain: ThoughtChain, conclusions: Conclusion[]): Promise<string> { let answer = `Based on comprehensive research analysis:\n\n`; conclusions.forEach((conclusion, index) => { answer += `${index + 1}. ${conclusion.statement}\n`; answer += ` Confidence: ${(conclusion.confidence * 100).toFixed(1)}%\n`; answer += ` Evidence strength: ${conclusion.supportingEvidence.length} supporting sources\n\n`; }); answer += `This analysis was conducted through ${thoughtChain.steps.length} research steps `; answer += `with an overall confidence of ${(thoughtChain.confidence * 100).toFixed(1)}%.`; return answer; } /** * 工具方法 */ private generateChainId(): string { return `chain-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; } private generateInitialReasoning(query: DecomposedQuery): string { return `Initial reasoning for ${query.type} query: "${query.subQuery}"`; } private initializeStepAnalysis(): StepAnalysis { return { relevanceScore: 0, qualityScore: 0, completenessScore: 0, consistencyScore: 0, noveltyScore: 0, evidenceStrength: 0, biasDetection: { detectedBiases: [], confidenceInDetection: 0, mitigationSuggestions: [] }, factualAccuracy: 0 }; } private calculateAverageRelevance(results: SearchResult[]): number { if (results.length === 0) return 0; return results.reduce((sum, result) => sum + result.relevanceScore, 0) / results.length; } private calculateAverageQuality(results: SearchResult[]): number { if (results.length === 0) return 0; return results.reduce((sum, result) => sum + result.qualityScore, 0) / results.length; } private assessCompleteness(results: SearchResult[], query: DecomposedQuery): number { // 简化的完整性评估 const expectedResults = query.metadata.maxResults; return Math.min(results.length / expectedResults, 1); } private assessConsistency(results: SearchResult[]): number { // 简化的一致性评估 return 0.8; // 默认值 } private assessNovelty(results: SearchResult[]): number { // 简化的新颖性评估 return 0.7; // 默认值 } private assessEvidenceStrength(results: SearchResult[]): number { return this.calculateAverageQuality(results); } private async detectBias(results: SearchResult[]): Promise<BiasAnalysis> { // 简化的偏见检测 return { detectedBiases: [], confidenceInDetection: 0.5, mitigationSuggestions: ['Consider diverse sources', 'Verify with multiple perspectives'] }; } private assessFactualAccuracy(results: SearchResult[]): number { // 简化的事实准确性评估 return 0.85; // 默认值 } private calculateStepConfidence(step: ThoughtStep): number { const analysis = step.analysis; return (analysis.relevanceScore + analysis.qualityScore + analysis.evidenceStrength) / 3; } private calculateOverallConfidence(thoughtChain: ThoughtChain, conclusions: Conclusion[]): number { const stepConfidences = thoughtChain.steps.map(step => step.confidence); if (stepConfidences.length === 0) return 0; return stepConfidences.reduce((sum, conf) => sum + conf, 0) / stepConfidences.length; } private calculateEvidenceQuality(thoughtChain: ThoughtChain): number { const allResults = thoughtChain.steps.flatMap(step => step.searchResults); return this.calculateAverageQuality(allResults); } private calculateCompleteness(thoughtChain: ThoughtChain, originalQuery: ResearchQuery): number { const completedSteps = thoughtChain.steps.filter(step => step.status === 'completed').length; return completedSteps / thoughtChain.steps.length; } private calculateExecutionMetrics(thoughtChain: ThoughtChain): ExecutionMetrics { const allResults = thoughtChain.steps.flatMap(step => step.searchResults); return { totalTime: thoughtChain.totalExecutionTime, searchTime: thoughtChain.steps.reduce((sum, step) => sum + step.executionTime * 0.6, 0), analysisTime: thoughtChain.steps.reduce((sum, step) => sum + step.executionTime * 0.3, 0), synthesisTime: thoughtChain.steps.reduce((sum, step) => sum + step.executionTime * 0.1, 0), queriesExecuted: thoughtChain.steps.length, resultsProcessed: allResults.length, averageRelevance: this.calculateAverageRelevance(allResults), averageQuality: this.calculateAverageQuality(allResults) }; } private calculateRecency(timestamp: string): number { const now = Date.now(); const resultTime = new Date(timestamp).getTime(); const daysDiff = (now - resultTime) / (1000 * 60 * 60 * 24); return Math.max(0, 1 - daysDiff / 365); // 1年内的内容认为是新的 } private synthesizeMainConclusion(stepConclusions: string[]): string { if (stepConclusions.length === 0) { return 'No sufficient evidence found to draw conclusions'; } return `Based on multi-step analysis, the research indicates: ${stepConclusions[0]}`; } private determineCertaintyLevel(thoughtChain: ThoughtChain): CertaintyLevel { const avgConfidence = this.calculateOverallConfidence(thoughtChain, []); if (avgConfidence >= 0.9) return 'very_high'; if (avgConfidence >= 0.75) return 'high'; if (avgConfidence >= 0.5) return 'moderate'; if (avgConfidence >= 0.25) return 'low'; return 'very_low'; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/flyanima/open-search-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server