diff --git a/backend/src/document-processor/services/aws-bedrock.service.ts b/backend/src/document-processor/services/aws-bedrock.service.ts index 06b86921..6f75ef49 100644 --- a/backend/src/document-processor/services/aws-bedrock.service.ts +++ b/backend/src/document-processor/services/aws-bedrock.service.ts @@ -56,6 +56,18 @@ Look for and extract the following information: This document may be a lab report showing blood work or other test results, so please pay special attention to tables, numeric values, reference ranges, and medical terminology. +IMPORTANT: Base your analysis on information from multiple trusted medical sources and authorities, including but not limited to: +- Mayo Clinic +- Cleveland Clinic +- CDC (Centers for Disease Control and Prevention) +- NIH (National Institutes of Health) +- WHO (World Health Organization) +- American Medical Association +- American Heart Association +- American Academy of Pediatrics +- UpToDate +- MedlinePlus + Format the response as a JSON object with the following structure: { "title": string, @@ -88,6 +100,7 @@ When extracting lab values: 4. Set "isCritical" to true when the value indicates an urgent medical situation. Set it to false for values that are normal or only slightly abnormal. 5. Include a "conclusion" field that provides a brief interpretation of what this value indicates about the patient's health 6. Include a "suggestions" field that provides brief recommendations based on this value +7. IMPORTANT: If reference ranges are missing from the document, add "reference-ranges-missing" to the missingInformation array in metadata, and use standard reference ranges from trusted medical sources to determine the status. EXTREMELY IMPORTANT FORMATTING INSTRUCTIONS: 1. ABSOLUTELY DO NOT START YOUR RESPONSE WITH ANY TEXT. Begin immediately with the JSON object. diff --git a/backend/src/document-processor/services/document-processor.service.ts b/backend/src/document-processor/services/document-processor.service.ts index 6b80a17e..e51233c7 100644 --- a/backend/src/document-processor/services/document-processor.service.ts +++ b/backend/src/document-processor/services/document-processor.service.ts @@ -55,12 +55,31 @@ export class DocumentProcessorService { }); // Step 2: Analyze extracted text using AWS Bedrock - const analysis = await this.bedrockService.analyzeMedicalDocument( + const initialAnalysis = await this.bedrockService.analyzeMedicalDocument( extractedText.rawText, userId, ); - // Step 3: Generate simplified explanation using Perplexity + // Step 3: Review and verify analysis using Perplexity + this.logger.log('Reviewing medical analysis with Perplexity'); + let analysis: MedicalDocumentAnalysis; + + try { + const verifiedAnalysis = await this.perplexityService.reviewMedicalAnalysis( + initialAnalysis, + extractedText.rawText, + ); + analysis = verifiedAnalysis; + this.logger.log('Analysis verified and possibly corrected by Perplexity'); + } catch (reviewError) { + this.logger.error('Error reviewing analysis with Perplexity', { + error: reviewError instanceof Error ? reviewError.message : 'Unknown error', + }); + // Fall back to initial analysis if review fails + analysis = initialAnalysis; + } + + // Step 4: Generate simplified explanation using Perplexity let simplifiedExplanation: string | undefined; try { diff --git a/backend/src/services/perplexity.service.ts b/backend/src/services/perplexity.service.ts index 329bec8c..1d20b7e7 100644 --- a/backend/src/services/perplexity.service.ts +++ b/backend/src/services/perplexity.service.ts @@ -96,11 +96,7 @@ export class PerplexityService { } /** - * Sends a chat completion request to the Perplexity API - * - * @param messages Array of messages for the conversation - * @param options Additional options for the request - * @returns The chat completion response + * Queries the Perplexity AI API */ async createChatCompletion( messages: PerplexityMessage[], @@ -166,4 +162,69 @@ export class PerplexityService { const response = await this.createChatCompletion(messages); return response.choices[0].message.content.trim(); } + + /** + * Reviews and verifies a medical document analysis against trusted medical sources + * + * @param analysis The medical document analysis to review + * @param originalText The original text of the medical document + * @returns The corrected medical document analysis + */ + async reviewMedicalAnalysis(analysis: any, originalText: string): Promise { + this.logger.log('Reviewing medical document analysis with Perplexity'); + + const systemPrompt = + 'You are an AI assistant specializing in medical information verification.\n' + + 'Your task is to review a medical document analysis and verify it against trusted medical sources.\n' + + 'You must ensure all information is accurate, especially lab value reference ranges and interpretations.\n' + + 'Use authoritative medical sources like Mayo Clinic, Cleveland Clinic, CDC, NIH, WHO, and medical journals.\n'; + + const analysisJson = JSON.stringify(analysis, null, 2); + + const userPrompt = + `Please review the following medical document analysis for accuracy and completeness. ` + + `Check if the lab value reference ranges, interpretations, and recommendations align with trusted medical sources. ` + + `Focus on these key aspects:\n` + + `1. Verify lab value reference ranges\n` + + `2. Confirm interpretations of abnormal values\n` + + `3. Validate medical conclusions and recommendations\n` + + `4. Ensure all lab values are correctly categorized\n\n` + + `If you find any discrepancies, provide corrections in your response by returning the corrected JSON directly.\n\n` + + `Medical Document Analysis:\n${analysisJson}\n\n` + + `Original Medical Document Text:\n${originalText}\n\n` + + `Return the corrected JSON analysis with the same structure, no preamble or explanation needed.`; + + const messages: PerplexityMessage[] = [ + { role: 'system', content: systemPrompt }, + { role: 'user', content: userPrompt }, + ]; + + try { + const response = await this.createChatCompletion(messages, { + temperature: 0.3, // Lower temperature for more accurate/factual responses + maxTokens: 4000, // Ensure there's enough space for the full corrected analysis + }); + + // Parse the response to get the corrected analysis + const responseText = response.choices[0].message.content.trim(); + + try { + // Try to parse as JSON - Perplexity should return the corrected JSON + const correctedAnalysis = JSON.parse(responseText); + return correctedAnalysis; + } catch (jsonParseError) { + // If parsing fails, log the error but return the original analysis + this.logger.error( + `Failed to parse Perplexity review response as JSON: ${jsonParseError instanceof Error ? jsonParseError.message : 'Unknown error'}`, + ); + return analysis; + } + } catch (error) { + // If the API call fails, log the error but return the original analysis + this.logger.error( + `Error during medical analysis review: ${error instanceof Error ? error.message : 'Unknown error'}`, + ); + return analysis; + } + } }