From 775d7eb1fbae97fd1b905a121885a32f0dabe7e5 Mon Sep 17 00:00:00 2001 From: VenkataKrishna Reddy Avula Date: Thu, 16 Oct 2025 21:49:33 +0000 Subject: [PATCH] Merged in bugfix/code_breakout_rev (pull request #739) bugfix/code_breakout_rev to main * added methodology to code explicit * pipeline fixes * Merged main into bugfix/code_breakout_rev * Remove prints Approved-by: Katon Minhas --- fieldExtraction/src/codes/code_funcs.py | 8 +++++--- fieldExtraction/src/prompts/prompt_templates.py | 9 +++++---- fieldExtraction/src/utils/llm_utils.py | 12 ------------ fieldExtraction/tests/test_code_funcs.py | 2 +- 4 files changed, 11 insertions(+), 20 deletions(-) diff --git a/fieldExtraction/src/codes/code_funcs.py b/fieldExtraction/src/codes/code_funcs.py index b050ff9..df38605 100644 --- a/fieldExtraction/src/codes/code_funcs.py +++ b/fieldExtraction/src/codes/code_funcs.py @@ -78,7 +78,7 @@ def get_regex_answers(service, code_answer_dict): return code_answer_dict -def code_explicit(service, filename): +def code_explicit(service, methodology, filename): """ Processes a service string and invokes a language model to generate a response based on the provided primary questions. The response is then parsed into a @@ -100,7 +100,7 @@ def code_explicit(service, filename): file_path=config.FIELD_JSON_PATH, field_type="code_primary_breakout" ).print_prompt_dict() claude_answer_raw = llm_utils.invoke_claude( - prompt_templates.CODE_EXPLICIT(service, code_primary_questions), + prompt_templates.CODE_EXPLICIT(service, methodology, code_primary_questions), "sonnet_latest", filename, ) @@ -531,6 +531,8 @@ def extract_codes_from_service(answer_dict, constants: Constants): service, bill_type = answer_dict.get("SERVICE_TERM"), answer_dict.get( "BILL_TYPE_CD_DESC" ) + filename = answer_dict.get("FILENAME") + methodology = answer_dict.get("REIMB_TERM") if string_utils.is_empty(service): return {} @@ -564,7 +566,7 @@ def extract_codes_from_service(answer_dict, constants: Constants): return answer_dict # Explicit Codes (run always) - code_answer_dict = code_explicit(service_clean, "") + code_answer_dict = code_explicit(service_clean, methodology, filename) if any( not string_utils.is_empty(value) for value in code_answer_dict.values() ) and all( diff --git a/fieldExtraction/src/prompts/prompt_templates.py b/fieldExtraction/src/prompts/prompt_templates.py index 2e3e68e..865cd66 100644 --- a/fieldExtraction/src/prompts/prompt_templates.py +++ b/fieldExtraction/src/prompts/prompt_templates.py @@ -668,10 +668,10 @@ def STOP_LOSS_BREAKOUT(term): ##################################################################################### -def CODE_EXPLICIT(service, questions): +def CODE_EXPLICIT(service, methodology, questions): return f"""Analyze a given medical service: -Use the text in the Service to populate a JSON dictionary with the following fields: +Use the text in the Service and Methodology to populate a JSON dictionary with the following fields: {questions}. @@ -681,10 +681,11 @@ Use the text in the Service to populate a JSON dictionary with the following fie - If the text describes an entire Code Category (not one specific code) based on a start letter, return the Category in the form "Category: X". e.g. "A-Codes" --> "Category: A", "K-Codes" --> "Category K", etc. - If the text explicitly says that there is no published or established rate, write "NOT_ESTABLISHED" for the PROCEDURE_CD value. - If any of the codes are not found, do not write a list for that field. Simply populate the field with an empty list []. -- If a 3-digit code is found without any explicit code type indicators (e.g., no mention of “DRG”, “revenue”, “Rev code”, etc.), check the surrounding text for contextual clues to determine whether it refers to a Revenue Code or a Grouper Code. If no clear context is found, default to classifying it as a GROUPER_CD. +- If a standalone 3-digit code appears without explicit labels (e.g., “DRG,” “revenue,” “Rev code”), analyze the surrounding context for clues. Look for any direct or indirect references—no matter how subtle—that may suggest a connection to either a Revenue Code or a Grouper Code. If any contextual clues imply relevance to either classification, categorize the code accordingly. -Here is the Service to analyze: +Here is the Service and Methodology to analyze: Service: {service.replace('"', "'")} +Methodology: {methodology.replace('"', "'")} Briefly explain your answer before putting the final answer in JSON dictionary format. """ diff --git a/fieldExtraction/src/utils/llm_utils.py b/fieldExtraction/src/utils/llm_utils.py index 56c6c08..16f1c02 100644 --- a/fieldExtraction/src/utils/llm_utils.py +++ b/fieldExtraction/src/utils/llm_utils.py @@ -439,9 +439,6 @@ def local_claude_3_and_up( # Print usage stats if available for debugging (cache creation/read tokens, etc.) if "usage" in response_body: label = usage_label or "UNLABELED" - print( - f"Usage stats [{label}] model={model_id} file={filename}: {response_body['usage']}" - ) response_text = response_body["content"][0]["text"] if config.ENABLE_ANSWER_TRACKING: @@ -536,9 +533,6 @@ def local_claude_3_and_up_with_image_array( # Print usage stats if available for debugging (cache creation/read tokens, etc.) if "usage" in response_body: label = usage_label or "UNLABELED" - print( - f"Usage stats [{label}] model={model_id} file={filename}: {response_body['usage']}" - ) response_text = response_body["content"][0]["text"] if config.ENABLE_ANSWER_TRACKING: @@ -701,9 +695,6 @@ def ec2_claude_3_and_up( # Print usage stats if available for debugging (cache creation/read tokens, etc.) if "usage" in response_body: label = usage_label or "UNLABELED" - print( - f"Usage stats [{label}] model={model_id} file={filename}: {response_body['usage']}" - ) response_text = response_body["content"][0]["text"] elapsed_time = time.time() - start_time @@ -770,9 +761,6 @@ def ec2_claude_3_and_up( # Print usage stats if available for debugging (cache creation/read tokens, etc.) if "usage" in response_body: label = usage_label or "UNLABELED" - print( - f"Usage stats [{label}] model={model_id} file={filename}: {response_body['usage']}" - ) response_text = response_body["content"][0]["text"] elapsed_time = time.time() - start_time diff --git a/fieldExtraction/tests/test_code_funcs.py b/fieldExtraction/tests/test_code_funcs.py index d5173e2..d96f94e 100644 --- a/fieldExtraction/tests/test_code_funcs.py +++ b/fieldExtraction/tests/test_code_funcs.py @@ -87,7 +87,7 @@ class TestCodeFuncs(unittest.TestCase): mock_json_load.return_value = {"PROCEDURE_CD": "12345"} # Test successful extraction - result = code_funcs.code_explicit("TEST SERVICE", "test.pdf") + result = code_funcs.code_explicit("TEST SERVICE","TEST_METHODOLOGY", "test.pdf") self.assertEqual(result, {"PROCEDURE_CD": "12345"}) mock_invoke_claude.assert_called_once()