Adds agent mock code
This commit is contained in:
703
scripts/langgraph_agent.py
Normal file
703
scripts/langgraph_agent.py
Normal file
@@ -0,0 +1,703 @@
|
|||||||
|
#!/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()
|
||||||
Reference in New Issue
Block a user