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
13 changes: 13 additions & 0 deletions backend/src/document-processor/services/aws-bedrock.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
71 changes: 66 additions & 5 deletions backend/src/services/perplexity.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[],
Expand Down Expand Up @@ -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<any> {
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;
}
}
}