704 lines
30 KiB
Python
704 lines
30 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Simple LangGraph agent using AWS Bedrock.
|
||
This agent demonstrates a basic ReAct-style agent with tool calling capabilities.
|
||
"""
|
||
|
||
import boto3
|
||
import csv
|
||
import json
|
||
from pathlib import Path
|
||
from typing import Annotated, TypedDict, Literal
|
||
from langgraph.graph import StateGraph, END
|
||
from langgraph.graph.message import add_messages
|
||
from langchain_aws import ChatBedrock
|
||
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage, SystemMessage
|
||
from langchain_core.tools import tool
|
||
|
||
# Global variable to store file content for the check tool
|
||
FILE = ""
|
||
CODE=""
|
||
|
||
# Base paths
|
||
SCRIPTS_DIR = Path(__file__).parent
|
||
JSON_OUTPUT_DIR = SCRIPTS_DIR / "json_output"
|
||
TEXTRACT_OUTPUT_DIR = SCRIPTS_DIR / "textract_output"
|
||
RULES={
|
||
"40808130":"""- Mulheres acima de 45 anos ou menopausada
|
||
- Homens com mais de 70 anos;
|
||
- Osteogênese imperfeita (para esta patologia, poderá haver a liberação de (02) dois
|
||
exames ao ano - cada 180 dias);
|
||
- RX com osteopenia ou fratura patológica;
|
||
- Antecedente pessoal de fratura após os 40 anos: punho, ombros, vértebras, quadril;
|
||
- Parente de primeiro grau com osteoporose.
|
||
- Mulheres com massa corporal <20kg/m2 ou peso < 57,8kg;
|
||
- Menopausa antes dos 45 anos ou hipogonasismo crônico (falência ovariana
|
||
precoce);
|
||
- Uso de glicocorticóides (>=7,5 prednizona/ dia equivalente por mais três meses, ou
|
||
presença de síndrome de cushing;
|
||
- Hiperparatireoidismo primário;
|
||
- Uso prolongado de anticonvulsivantes (< 10 anos);
|
||
- Síndrome de má absorção crônica ou desnutrição doenças inflamatória intestinal
|
||
(independente da causa: bariatrica, celiacos, intolerancia a lactose).
|
||
- Quimioterapia, se sobrevida esperada for longa (< 5 anos);
|
||
- Diminuição documentada de altura;
|
||
- Presença de cifose após menopausa.
|
||
- Imobilização prolongada""",
|
||
"40808122":"""- Mulheres acima de 45 anos ou menopausada
|
||
- Homens com mais de 70 anos;
|
||
- Osteogênese imperfeita (para esta patologia, poderá haver a liberação de (02) dois
|
||
exames ao ano - cada 180 dias);
|
||
- RX com osteopenia ou fratura patológica;
|
||
- Antecedente pessoal de fratura após os 40 anos: punho, ombros, vértebras, quadril;
|
||
- Parente de primeiro grau com osteoporose.
|
||
- Mulheres com massa corporal <20kg/m2 ou peso < 57,8kg;
|
||
- Menopausa antes dos 45 anos ou hipogonasismo crônico (falência ovariana
|
||
precoce);
|
||
- Uso de glicocorticóides (>=7,5 prednizona/ dia equivalente por mais três meses, ou
|
||
presença de síndrome de cushing;
|
||
- Hiperparatireoidismo primário;
|
||
- Uso prolongado de anticonvulsivantes (< 10 anos);
|
||
- Síndrome de má absorção crônica ou desnutrição doenças inflamatória intestinal
|
||
(independente da causa: bariatrica, celiacos, intolerancia a lactose).
|
||
- Quimioterapia, se sobrevida esperada for longa (< 5 anos);
|
||
- Diminuição documentada de altura;
|
||
- Presença de cifose após menopausa.
|
||
- Imobilização prolongada""",
|
||
"31303293":"""Mirena e Kyleena possuem critérios diferentes para autorização.
|
||
Autorizar sem o parecer da Auditoria Médica, somente quando for beneficiária com
|
||
idade entre 18 e 45 anos e se o formulário estiver preenchido conforme as quatro
|
||
validações abaixo:
|
||
· Identificação completa do paciente e médico assistente;
|
||
· Campo 1.1: selecionado: Mirena ou Kyleena;
|
||
· Campo 1.2: selecionado:
|
||
· Mirena: Menorragia idiopática (sangramento) ou Anticoncepção; ou Kyleena:
|
||
Anticoncepção;
|
||
· Se os itens 2 e 3 estiverem descritos como “NÃO”, “NÃO SE APLICA”, “- “ou EM
|
||
BRANCO.
|
||
Encaminhar para a auditoria médica (Mirena ou Kyleena) somente quando:
|
||
- Solicitações que incluam outros eventos além do implante de DIU;
|
||
- Constar pedido de liberação de anestesia;
|
||
- No caso de prazo intervalar - Incluir na perícia, a negação gerada e qual a finalidade
|
||
da análise do auditor, informar também a data da última liberação do DIU e a
|
||
necessidade de avaliação por conta do prazo de repetição.
|
||
- Campo 1.1 selecionado: “Outros”;
|
||
- Campo 1.2 selecionado:
|
||
Mirena: “Outros” ou nenhuma opção selecionada;Kyleena: Menorragia idiopática (Sangramento) ou “Outros”;
|
||
- Se qualquer campo dos itens 2 e 3 descreverem alguma contraindicação.
|
||
- Beneficiária menor de 18 anos ou acima de 45 anos.""",
|
||
"31005470":"""Autorizar sem o parecer da Auditoria Médica se constar no pedido médico ou
|
||
laudos, uma das justificativas abaixo:
|
||
·Cálculo biliar;
|
||
·Colelitíase;
|
||
·Litíase;
|
||
·Pólipos acima de 01 cm.
|
||
Caso a indicação seja outra ou pólipo menor que 01 cm, encaminhar para
|
||
auditoria.""",
|
||
"41501012":"""Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÃMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Autorizar sem o parecer da Auditoria Médica solicitações de beneficiários acima de
|
||
60 anos.Autorizar independentemente da idade solicitações em que a justificativa indique
|
||
pelo menos uma das patologias abaixo:
|
||
·
|
||
4)Catarata senil (CID’S H25-1, H25-2, H25-8, H25-9, H26-1, H26-2, H26-3, H26-
|
||
·Outros transtornos do cristalino.
|
||
BANDEJA
|
||
Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÃMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
- Bandeja 143 - AML - OFTALMOLOGIA - obrigatoriamente com a documentação
|
||
mínima.
|
||
- Bandeja 51 - AML - SEM INFORMAÇÃO MÍNIMA PARA ANÁLISE: Quando for
|
||
solicitação eletiva e não houver indicação clínica.
|
||
Botão Prioridade: Em caso de beneficiário Intercâmbio, PAC, GLP ou SAC Empresa, é
|
||
obrigatório selecionar a bandeja de retorno no botão prioridade, para correta
|
||
devolução ao responsável.
|
||
ATENDIMENTO INTERCÃMBIO
|
||
IMPORTADO (Beneficiários de Outras Unimed's sendo atendidos em Curitiba e
|
||
região).
|
||
1°Passo: Necessário documentação conforme planilha de racionalização.
|
||
2° Passo: Gerar a solicitação em sistema com documentação em anexo.
|
||
- Se tiver a documentação, anexar no sistema (ATF não necessita anexar).
|
||
- Se não tiver documentação, solicitar que beneficiário providencie para dar entrada.3° Passo: Verificar no monitor de intercâmbio, se o processo está pendente de
|
||
perícia.
|
||
- Se tiver, abrir sala CHAT e anexar as documentações (ATF não necessita anexar).
|
||
- Se não tiver, abrir GPU (ATF não necessita abertura).
|
||
4° Passo: Deixar processo pendente na bandeja para monitoramento.
|
||
-Se trafegou, bandeja 921.
|
||
-Se não trafegou, bandeja 11.
|
||
5° Passo: Registrar em anotações administrativas as informações pertinentes ao
|
||
processo.""",
|
||
"40901254":"""Autorizar no ato do atendimento a 1ª solicitação entre o período (DE 11- 14 SEMANAS
|
||
DE GESTAÇÃO).
|
||
ou
|
||
Se o evento foi gerado decorrente da consulta obstétrica 1.01.01987 - CONSULTA
|
||
OBSTÉTRICA - 2ª AVALIAÇÃO (ATÉ 10 SEMANAS DE GESTAÇÃO).""",
|
||
"40901262":"""Autorizar no ato do atendimento a 1ª solicitação entre o período de 18 a 24 semanas
|
||
de gestação ou se o evento foi gerado decorrente da consulta obstétrica 1.01.01989
|
||
- CONSULTA OBSTÉTRICA - 4ª AVALIAÇÃO (ATÉ 18 SEMANAS DE GESTAÇÃO).A repetição poderá ser autorizada desde que se enquadre em um dos critérios
|
||
abaixo:
|
||
·Anomalia fetal diagnosticada em exame de rotina.
|
||
·Antecedentes de doenças hereditárias.
|
||
·Consanguinidade.
|
||
·Exposição a drogas.
|
||
·Idade materna avançada.
|
||
·Infecções pré-natais.""",
|
||
"4091262":"""Autorizar no ato do atendimento a 1ª solicitação entre o período de 18 a 24 semanas
|
||
de gestação ou se o evento foi gerado decorrente da consulta obstétrica 1.01.01989
|
||
- CONSULTA OBSTÉTRICA - 4ª AVALIAÇÃO (ATÉ 18 SEMANAS DE GESTAÇÃO).A repetição poderá ser autorizada desde que se enquadre em um dos critérios
|
||
abaixo:
|
||
·Anomalia fetal diagnosticada em exame de rotina.
|
||
·Antecedentes de doenças hereditárias.
|
||
·Consanguinidade.
|
||
·Exposição a drogas.
|
||
·Idade materna avançada.
|
||
·Infecções pré-natais.""",
|
||
"40304906":"""Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÃMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Poderá ser liberada de imediato as solicitações eletivas que contenha a indicação
|
||
abaixo, conforme DUT:
|
||
•
|
||
Avaliação de pacientes adultos com sinais e sintomas de trombose
|
||
venosa profunda dos membros inferiores;
|
||
URGÊNCIA/EMERGÊNCIA (INTERNAMENTO e AMBULATORIAL)
|
||
Poderá ser liberada de imediato as solicitações de Urgência e Emergência em regime
|
||
Internamento ou em situação de Observação em Unidades de Urgência que
|
||
contenha a indicação:
|
||
•
|
||
Pacientes adultos com sinais e sintomas de embolia pulmonar.
|
||
•
|
||
Pneumonia ou síndrome respiratória aguda grave, com quadro suspeito ou
|
||
confirmado de infecção pelo SARS-CoV-2 (COVID 19).
|
||
PLANOS NÃO REGULAMENTADOS E PLANOS ADAPTADOS
|
||
Os planos não regulamentados (UNIPLAN, UNIPLAN 2000 E NOVO UNIPLAN) e
|
||
adaptados, asseguram cobertura ilimitada para exames laboratoriais, pois não
|
||
seguem o Rol e as diretrizes de utilização. Desta forma podem ser autorizados
|
||
segundo regras contratuais.""",
|
||
|
||
"20203020":"""utorizar sem o parecer da Auditoria Médica desde
|
||
que a justificativa indique pelo menos uma das patologias abaixo ou CID’s
|
||
relacionados:·Incontinência urinária (CID R32);
|
||
·Disfunção miccional (CID N39);
|
||
·Incontinência de tensão (“stress”) (CID N39.3);
|
||
·Síndrome da bexiga hiperativa;
|
||
·Distúrbios do assoalho pélvico;
|
||
·Incontinência fecal (CID R15);
|
||
·Outros transtornos funcionais do intestino (CID K59);
|
||
·Fortalecimento do Assoalho Pélvico pré e/ou pós-parto.""",
|
||
"41001230":"""PROTOCOLO DE LIBERAÇÃO
|
||
Para beneficiário de outras Unimed’s (importado)
|
||
Ver item ATENDIMENTO INTERCÂMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Todas as solicitações devem ser direcionadas para análise da Auditoria Médica,
|
||
com a documentação mínima.""",
|
||
"4034906":"""Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÃMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Poderá ser liberada de imediato as solicitações eletivas que contenha a indicação
|
||
abaixo, conforme DUT:
|
||
•
|
||
Avaliação de pacientes adultos com sinais e sintomas de trombose
|
||
venosa profunda dos membros inferiores;
|
||
URGÊNCIA/EMERGÊNCIA (INTERNAMENTO e AMBULATORIAL)
|
||
Poderá ser liberada de imediato as solicitações de Urgência e Emergência em regime
|
||
Internamento ou em situação de Observação em Unidades de Urgência que
|
||
contenha a indicação:
|
||
•
|
||
Pacientes adultos com sinais e sintomas de embolia pulmonar.
|
||
•
|
||
Pneumonia ou síndrome respiratória aguda grave, com quadro suspeito ou
|
||
confirmado de infecção pelo SARS-CoV-2 (COVID 19).
|
||
PLANOS NÃO REGULAMENTADOS E PLANOS ADAPTADOS
|
||
Os planos não regulamentados (UNIPLAN, UNIPLAN 2000 E NOVO UNIPLAN) e
|
||
adaptados, asseguram cobertura ilimitada para exames laboratoriais, pois não
|
||
seguem o Rol e as diretrizes de utilização. Desta forma podem ser autorizados
|
||
segundo regras contratuais.""",
|
||
"4101230":"""PROTOCOLO DE LIBERAÇÃO
|
||
Para beneficiário de outras Unimed’s (importado)
|
||
Ver item ATENDIMENTO INTERCÂMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Todas as solicitações devem ser direcionadas para análise da Auditoria Médica,
|
||
com a documentação mínima.""",
|
||
"20103190":"""Autorizar sem o parecer da Auditoria Médica desde que a justificativa indique pelo
|
||
menos uma das patologias abaixo ou CID’s relacionados:
|
||
·Incontinência urinária (CID R32);
|
||
·Disfunção miccional (CID N39);
|
||
·Incontinência de tensão (“stress”) (CID N39.3);·Síndrome da bexiga hiperativa;
|
||
·Distúrbios do assoalho pélvico;
|
||
·Incontinência fecal (CID R15);
|
||
·Outros transtornos funcionais do intestino (CID K59);
|
||
·Fortalecimento do Assoalho Pélvico pré e/ou pós-parto.
|
||
BENEFICIARIOS ADULTOS (ACIMA DE 18 ANOS):
|
||
Se a solicitação estiver enquadrada nas indicações acima poderá ser autorizado sem
|
||
encaminhar para o AML até 10 quantidades ao mês;
|
||
Ponto de atenção - pertinente 10 sessões total ao mês: considerar códigos
|
||
associados ou individuais (eletroestimulação do assoalho pélvico, disfunção vesico
|
||
uretral, biofeedback, reabilitação perineal)
|
||
BENEFICIARIOS CRIANÇAS (ATÉ 17 ANOS E 11 MESES):
|
||
Se a solicitaçãoEste evento está parametrizado para autorizar automaticamente para beneficiários
|
||
carteirinha 0032.
|
||
· Para beneficiários PAC, início do cartão 09759032, as solicitações destes exames
|
||
devem ser liberadas de imediato, revertendo a guia no motivo: 9 - AUTORIZADO
|
||
CONFORME PROTOCOLO DE LIBERAÇÃO· Para beneficiários 0032 no intercâmbio exportado, as solicitações destes exames
|
||
devem ser liberadas de imediato, revertendo a guia no motivo: 9 - AUTORIZADO
|
||
CONFORME PROTOCOLO DE LIBERAÇÃO
|
||
NÃO NEGAR ATENDIMENTO.
|
||
ATENÇÃO: Exame contratualizado para realização na Unimed Laboratório,
|
||
exclusivamente na Megaunidade.
|
||
Telefone de contato para mais informações: (41) 3021-5252.
|
||
ATENDIMENTO INTERCÂMBIO
|
||
Encaminhar para deliberação da Unimed origem. estiver enquadrada nas indicações acima poderá ser autorizado sem
|
||
encaminhar para o AML até 04 quantidades ao mês;
|
||
Ponto de atenção - pertinente 04 sessões ao mês: para cada modalidade
|
||
(eletroestimulação do assoalho pélvico, disfunção vesico uretral, biofeedback,
|
||
reabilitação perineal)
|
||
Acima desta quantidade encaminhar para a análise da Auditoria Médica com
|
||
justificativa médica.""",
|
||
"40202542":"""Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÃMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Esse código não requer análise da Auditoria Médica, analisar baseado na cobertura e
|
||
limite contratual do beneficiário.
|
||
Caso seja necessário análise da auditoria médica devido alguma mensagem de
|
||
negação, consultar o item "Documentação Mínima".
|
||
Para beneficiário Unimed 0032 (atendimento em outra singular/Exportado):
|
||
A liberação do procedimento não está condicionada a solicitação dos materiais, pois
|
||
o mesmo poderá ser realizado sem a utilização da "Alça de Polipectomia" e da
|
||
“Agulha de Esclerose ou Injetor”.
|
||
Quando houver solicitação dos materiais posteriormente à autorização do evento,
|
||
não há a necessidade de análise da AML para os materiais. Deverá ser cadastrado
|
||
conforme informações acima e, liberar. (Circular n.º 056/2008 de 01/08/2008).""",
|
||
"40202550":"""Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÃMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Esse código não requer análise da Auditoria Médica, analisar baseado na cobertura e
|
||
limite contratual do beneficiário.
|
||
Caso seja necessário análise da auditoria médica devido alguma mensagem de
|
||
negação, consultar o item "Documentação Mínima".
|
||
Para beneficiário Unimed 0032 (atendimento em outra singular/Exportado):
|
||
A liberação do procedimento não está condicionada a solicitação dos materiais, pois
|
||
o mesmo poderá ser realizado sem a utilização da "Alça de Polipectomia" e da
|
||
“Agulha de Esclerose ou Injetor”.
|
||
Quando houver solicitação dos materiais posteriormente à autorização do evento,
|
||
não há a necessidade de análise da AML para os materiais. Deverá ser cadastrado
|
||
conforme informações acima e, liberar. (Circular n.º 056/2008 de 01/08/2008).""",
|
||
"40323676":"""Este evento está parametrizado para autorizar automaticamente para beneficiários
|
||
carteirinha 0032.
|
||
· Para beneficiários PAC, início do cartão 09759032, as solicitações destes exames
|
||
devem ser liberadas de imediato, revertendo a guia no motivo: 9 - AUTORIZADO
|
||
CONFORME PROTOCOLO DE LIBERAÇÃO· Para beneficiários 0032 no intercâmbio exportado, as solicitações destes exames
|
||
devem ser liberadas de imediato, revertendo a guia no motivo: 9 - AUTORIZADO
|
||
CONFORME PROTOCOLO DE LIBERAÇÃO
|
||
NÃO NEGAR ATENDIMENTO.
|
||
ATENÇÃO: Exame contratualizado para realização na Unimed Laboratório,
|
||
exclusivamente na Megaunidade.
|
||
Telefone de contato para mais informações: (41) 3021-5252.
|
||
ATENDIMENTO INTERCÂMBIO
|
||
Encaminhar para deliberação da Unimed origem.""",
|
||
|
||
|
||
}
|
||
MIN_DOC={
|
||
"20103190":"""DOCUMENTAÇÃO MÍNIMA
|
||
Justificativa Médica e/ou indicação clínica.""",
|
||
"20203020":"""DOCUMENTAÇÃO MÍNIMA:
|
||
·
|
||
Justificativa Médica e/ou indicação clínica.""",
|
||
"31303293":"""DOCUMENTAÇÃO MÍNIMA
|
||
Beneficiário 0032 (atendidos em Curitiba e em Outras cidades):
|
||
·Justificativa médica e/ou indicação clínica;
|
||
·Formulário de Solicitação - DIU Hormonal (ver anexo do script).
|
||
Beneficiário Intercâmbio/Outras Unimeds:
|
||
·
|
||
Relatório Médico Detalhado (conforme racionalização).""",
|
||
"40202542":"""DOCUMENTAÇÃO MÍNIMA
|
||
Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÃMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Justificativa Médica e/ou indicação clínica.""",
|
||
"40202550":"""DOCUMENTAÇÃO MÍNIMA
|
||
Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÃMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Justificativa Médica e/ou indicação clínica.""",
|
||
"40304906":"""DOCUMENTAÇÃO MÍNIMA
|
||
Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÃMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Justificativa e/ou indicação clínica.""",
|
||
"4034906":"""DOCUMENTAÇÃO MÍNIMA
|
||
Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÃMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Justificativa e/ou indicação clínica.""",
|
||
"40314626":"""DOCUMENTAÇÃO MÍNIMA
|
||
Não há;""",
|
||
"40314618":"""DOCUMENTAÇÃO MÍNIMA
|
||
Não há;""",
|
||
"40323676":"""DOCUMENTAÇÃO MÍNIMA
|
||
Não há;""",
|
||
"40901254":"""Justificativa Médica e/ou indicação clínica informando a idade gestacional e Laudo
|
||
do 1º exame sonográfico gestacional realizado.""",
|
||
"40901262":"""DOCUMENTAÇÃO MÍNIMA
|
||
Relatório médico informando a idade gestacional + laudo do 1o exame sonográfico
|
||
gestacional realizado.""",
|
||
"4091262":"""DOCUMENTAÇÃO MÍNIMA
|
||
Relatório médico informando a idade gestacional + laudo do 1o exame sonográfico
|
||
gestacional realizado.""",
|
||
"4101230":"""DOCUMENTAÇÃO MÍNIMA
|
||
Para beneficiário de outras Unimed’s (importado)
|
||
Ver item ATENDIMENTO INTERCÂMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
·
|
||
Relatório Médico detalhado com histórico indicando a necessidade de
|
||
realização do exame, além de sinais e sintomas, se possui limitação para teste de
|
||
esforço físico;
|
||
·
|
||
Índice de pré-teste segundo os critérios de Diamons e Forrester revisados
|
||
e/ ou TIMI risk;
|
||
·
|
||
Laudos de exames cardiológicos recentes.""",
|
||
"4101230":"""DOCUMENTAÇÃO MÍNIMA
|
||
Para beneficiário de outras Unimed’s (importado)
|
||
Ver item ATENDIMENTO INTERCÂMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
·
|
||
Relatório Médico detalhado com histórico indicando a necessidade de
|
||
realização do exame, além de sinais e sintomas, se possui limitação para teste de
|
||
esforço físico;
|
||
·
|
||
Índice de pré-teste segundo os critérios de Diamons e Forrester revisados
|
||
e/ ou TIMI risk;
|
||
·
|
||
Laudos de exames cardiológicos recentes.""",
|
||
"41501144":"""DOCUMENTAÇÃO MÍNIMA
|
||
PARA BENEFICIÁRIOS 0032 SENDO ATENDIDO EM CURITIBA, FORA (EXPORTADO),
|
||
E PAC:
|
||
·
|
||
Relatório Médico descrevendo a necessidade de realização do exame.·
|
||
Se o pedido for para avaliação de glaucoma, é necessário incluir laudo e
|
||
imagem da retinografia.
|
||
Atenção: Para as demais situações, NÃO é necessário enviar o laudo da retinografia.
|
||
PARA BENEFICIÁRIOS INTERCÂMBIO ESTADUAL, CONFORME DETERMINAÇÃO
|
||
DO CERS
|
||
·Relatório médico descrevendo a necessidade da realização do exame;
|
||
·Laudo e imagem de retinografia.
|
||
Atenção: NÃO É OBRIGATÓRIO o envio do laudo e imagem de retinografia para:
|
||
> Pacientes com diagnóstico da doença já confirmado e que estejam em tratamento
|
||
com aplicação de antiangiogênicos, para as patologias abaixo:
|
||
·Doença Macular Relacionada à Idade (DMRI);
|
||
·Oclusões Vasculares Retinianas;
|
||
·Edema Macular secundário a Diabetes Mellitus.
|
||
Caso a informação referente ao tratamento não conste no relatório médico, consultar
|
||
eventos recentes para identificar se o beneficiário está em tratamento.
|
||
Esclarecemos que o envio de retinografia, poderá eventualmente ser solicitado pela
|
||
auditoria para fins de elucidação diagnóstica.
|
||
PARA BENEFICIÁRIOS INTERCÂMBIO NACIONAL:
|
||
SEGUIR DOCUMENTAÇÃO CONFORME RACIONALIZAÇÃO.""",
|
||
"31005101":"""DOCUMENTAÇÃO MÍNIMA:
|
||
·Relatório médico detalhado;
|
||
·Laudo RX e/ou tomografia e/ou ressonância e/ou ultrassonografia.""",
|
||
"31005470":"""DOCUMENTAÇÃO MÍNIMA:
|
||
·Relatório médico detalhado;
|
||
·Laudo RX e/ou tomografia e/ou ressonância e/ou ultrassonografia.""",
|
||
"40808122":"""DOCUMENTAÇÃO MÍNIMA
|
||
Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÂMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Justificativa e/ou indicação clínica.""",
|
||
"40808130":"""DOCUMENTAÇÃO MÍNIMA
|
||
Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÂMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Justificativa e/ou indicação clínica.""",
|
||
"41501012":"""Para beneficiário de outras Unimed’s (importado):
|
||
Ver item ATENDIMENTO INTERCÃMBIO.
|
||
Para beneficiário Unimed 0032 (atendimento local):
|
||
Justificativa médica e/ou indicação clínica."""
|
||
}
|
||
# System prompt for the agent
|
||
|
||
# Define tools the agent can use
|
||
@tool
|
||
def check(expression: str) -> str:
|
||
"""Retrieves the values of the files associated with the input for aditional information, if the json is not enough"""
|
||
return FILE
|
||
|
||
# Define the agent state
|
||
class AgentState(TypedDict):
|
||
messages: Annotated[list, add_messages]
|
||
|
||
|
||
def get_bedrock_client():
|
||
"""Initialize and return AWS Bedrock runtime client."""
|
||
return boto3.client("bedrock-runtime", region_name="us-east-2")
|
||
|
||
|
||
def create_llm():
|
||
"""Create and return the Bedrock LLM."""
|
||
return ChatBedrock(
|
||
model_id="arn:aws:bedrock:us-east-2:232048051668:application-inference-profile/uy4xskop19zn",
|
||
region_name="us-east-2",
|
||
provider="anthropic"
|
||
)
|
||
|
||
|
||
|
||
def create_agent():
|
||
"""Create and return the LangGraph agent."""
|
||
|
||
# Initialize the LLM with tools
|
||
llm = create_llm()
|
||
tools = [check]
|
||
llm_with_tools = llm.bind_tools(tools)
|
||
|
||
# Create tool lookup
|
||
tool_map = {tool.name: tool for tool in tools}
|
||
|
||
# Define the agent node
|
||
def call_model(state: AgentState) -> dict:
|
||
"""Call the LLM with the current state."""
|
||
messages = state["messages"]
|
||
response = llm_with_tools.invoke(messages)
|
||
return {"messages": [response]}
|
||
|
||
# Define the tool execution node
|
||
def call_tools(state: AgentState) -> dict:
|
||
"""Execute tools based on the last message."""
|
||
last_message = state["messages"][-1]
|
||
tool_messages = []
|
||
|
||
for tool_call in last_message.tool_calls:
|
||
tool_name = tool_call["name"]
|
||
tool_args = tool_call["args"]
|
||
|
||
if tool_name in tool_map:
|
||
result = tool_map[tool_name].invoke(tool_args)
|
||
tool_messages.append(
|
||
ToolMessage(content=str(result), tool_call_id=tool_call["id"])
|
||
)
|
||
else:
|
||
tool_messages.append(
|
||
ToolMessage(
|
||
content=f"Tool {tool_name} not found",
|
||
tool_call_id=tool_call["id"],
|
||
)
|
||
)
|
||
|
||
return {"messages": tool_messages}
|
||
|
||
# Define the routing function
|
||
def should_continue(state: AgentState) -> Literal["tools", "end"]:
|
||
"""Determine whether to continue with tools or end."""
|
||
last_message = state["messages"][-1]
|
||
if hasattr(last_message, "tool_calls") and last_message.tool_calls:
|
||
return "tools"
|
||
return "end"
|
||
|
||
# Build the graph
|
||
workflow = StateGraph(AgentState)
|
||
|
||
# Add nodes
|
||
workflow.add_node("agent", call_model)
|
||
workflow.add_node("tools", call_tools)
|
||
|
||
# Set entry point
|
||
workflow.set_entry_point("agent")
|
||
|
||
# Add conditional edges
|
||
workflow.add_conditional_edges(
|
||
"agent",
|
||
should_continue,
|
||
{
|
||
"tools": "tools",
|
||
"end": END,
|
||
},
|
||
)
|
||
|
||
# Add edge from tools back to agent
|
||
workflow.add_edge("tools", "agent")
|
||
|
||
# Compile the graph
|
||
return workflow.compile()
|
||
|
||
|
||
def run_agent(query: str,code:str) -> str:
|
||
"""
|
||
Run the agent with a given query.
|
||
|
||
Args:
|
||
query: The user's question or request
|
||
|
||
Returns:
|
||
The agent's final response
|
||
"""
|
||
agent = create_agent()
|
||
SYSTEM_PROMPT = """You are a AI assistant responsible to check if a person is Allowed or Denied acces to medical procedure based on the following rules:
|
||
<rules>
|
||
"""+RULES[code]+""""
|
||
<\rules>
|
||
Also this is the required documentation for aproval, try to indetify every document as one of these, or not identified:
|
||
"""+MIN_DOC[code]+""""
|
||
Your capabilities:
|
||
- You can check the OCR of anexed documents if the json input is not enough to determinate if it should be aproved, using the check tool.
|
||
|
||
|
||
Start your answer with either:
|
||
Aproved: if any of the rules are met, firts look only at the input, then check the file
|
||
Reproved: If there aren't any rules met.
|
||
|
||
And list the document classification and the met criteira, in case of aprovation. Be really precise and succint"""
|
||
|
||
initial_state = {
|
||
"messages": [
|
||
SystemMessage(content=SYSTEM_PROMPT),
|
||
HumanMessage(content=query)
|
||
]
|
||
}
|
||
|
||
print(f"\nUser: {query}")
|
||
print("-" * 50)
|
||
|
||
# Run the agent
|
||
final_state = agent.invoke(initial_state)
|
||
|
||
# Get the final response
|
||
final_message = final_state["messages"][-1]
|
||
response = final_message.content if hasattr(final_message, "content") else str(final_message)
|
||
|
||
print(f"Agent: {response}")
|
||
return response
|
||
|
||
|
||
def get_textract_folder_for_guia(numero_guia: str) -> Path | None:
|
||
"""Find the textract output folder that starts with the numeroGuia."""
|
||
for folder in TEXTRACT_OUTPUT_DIR.iterdir():
|
||
if folder.is_dir() and folder.name.startswith(numero_guia):
|
||
return folder
|
||
return None
|
||
|
||
|
||
def load_txt_files_from_folder(folder: Path) -> str:
|
||
"""Load and concatenate all .txt files from a folder."""
|
||
content_parts = []
|
||
for txt_file in sorted(folder.glob("*.txt")):
|
||
content_parts.append(f"--- {txt_file.name} ---\n{txt_file.read_text()}")
|
||
return "\n\n".join(content_parts)
|
||
|
||
|
||
def main():
|
||
"""Main function to process JSON files and run the agent."""
|
||
global FILE
|
||
|
||
print("=" * 60)
|
||
print("LangGraph Agent with AWS Bedrock")
|
||
print("=" * 60)
|
||
|
||
# Prepare CSV output
|
||
output_csv_path = SCRIPTS_DIR / "agent_results.csv"
|
||
results = []
|
||
|
||
# Iterate over all JSON files in json_output folder
|
||
for json_file in sorted(JSON_OUTPUT_DIR.glob("*.json")):
|
||
print(f"\nProcessing: {json_file.name}")
|
||
print("-" * 60)
|
||
|
||
# Load JSON data
|
||
with open(json_file, "r", encoding="utf-8") as f:
|
||
data = json.load(f)
|
||
|
||
# Get numeroGuia
|
||
numero_guia = data.get("numeroGuia")
|
||
nome_beneficiario = data.get("nomeBeneficiario", "")
|
||
resultado_da_analise = data.get("Resultado_da_analise", "")
|
||
por_que_libera = data.get("Por_que_libera?", "")
|
||
|
||
# Skip if numeroGuia is NaN or None
|
||
if numero_guia is None or (isinstance(numero_guia, float) and str(numero_guia) == "nan"):
|
||
skip_reason = "numeroGuia is NaN or missing"
|
||
print(f" Skipping: {skip_reason}")
|
||
results.append({
|
||
"numeroGuia": str(numero_guia) if numero_guia else "",
|
||
"nomeBeneficiario": nome_beneficiario,
|
||
"Resultado_da_analise": resultado_da_analise,
|
||
"Por_que_libera": por_que_libera,
|
||
"agent_output": f"SKIPPED: {skip_reason}"
|
||
})
|
||
continue
|
||
|
||
numero_guia = str(numero_guia)
|
||
print(f" numeroGuia: {numero_guia}")
|
||
|
||
# Find corresponding textract folder
|
||
textract_folder = get_textract_folder_for_guia(numero_guia)
|
||
if textract_folder is None:
|
||
skip_reason = f"No textract folder found for {numero_guia}"
|
||
print(f" Skipping: {skip_reason}")
|
||
results.append({
|
||
"numeroGuia": numero_guia,
|
||
"nomeBeneficiario": nome_beneficiario,
|
||
"Resultado_da_analise": resultado_da_analise,
|
||
"Por_que_libera": por_que_libera,
|
||
"agent_output": f"SKIPPED: {skip_reason}"
|
||
})
|
||
continue
|
||
|
||
print(f" Textract folder: {textract_folder.name}")
|
||
|
||
# Load txt files content into FILE global variable
|
||
FILE = load_txt_files_from_folder(textract_folder)
|
||
|
||
# Get codigoServico and convert to numerical string (remove dots/special chars)
|
||
codigo_servico = data.get("codigoServico", "")
|
||
code = "".join(c for c in str(codigo_servico) if c.isdigit())
|
||
|
||
# Skip if code not in RULES
|
||
if code not in RULES:
|
||
skip_reason = f"codigoServico '{codigo_servico}' (code: {code}) not in RULES"
|
||
print(f" Skipping: {skip_reason}")
|
||
results.append({
|
||
"numeroGuia": numero_guia,
|
||
"nomeBeneficiario": nome_beneficiario,
|
||
"Resultado_da_analise": resultado_da_analise,
|
||
"Por_que_libera": por_que_libera,
|
||
"agent_output": f"SKIPPED: {skip_reason}"
|
||
})
|
||
continue
|
||
|
||
print(f" codigoServico: {codigo_servico} -> code: {code}")
|
||
|
||
# Remove fields that should not be sent to the agent
|
||
fields_to_drop = ["Resultado_da_analise", "Onde_foi_liberado", "Canal_de_entrada", "Por_que_libera?"]
|
||
for field in fields_to_drop:
|
||
data.pop(field, None)
|
||
|
||
# Run the agent with the JSON data as query
|
||
query = json.dumps(data, indent=2, ensure_ascii=False)
|
||
agent_output = run_agent(query, code)
|
||
|
||
# Add result to list
|
||
results.append({
|
||
"numeroGuia": numero_guia,
|
||
"nomeBeneficiario": nome_beneficiario,
|
||
"Resultado_da_analise": resultado_da_analise,
|
||
"Por_que_libera": por_que_libera,
|
||
"agent_output": agent_output
|
||
})
|
||
|
||
print("\n" + "=" * 60)
|
||
|
||
# Write results to CSV
|
||
with open(output_csv_path, "w", encoding="utf-8", newline="") as csvfile:
|
||
fieldnames = ["numeroGuia", "nomeBeneficiario", "Resultado_da_analise", "Por_que_libera", "agent_output"]
|
||
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
|
||
writer.writeheader()
|
||
writer.writerows(results)
|
||
|
||
print(f"\nResults saved to: {output_csv_path}")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|