Projeto IA.med Licença Apache-2.0 Experimento de pesquisa

raciocinio-br-mcp

Raciocínio clínico em contexto brasileiro num LLM local: o que ele acerta, o que ele erra, e a avaliação publicada junto com o código.

Isto não é apoio à decisão clínica

  • Não é apoio à decisão clínica e não substitui o julgamento médico.
  • Não tem validação prospectiva e não foi avaliado por nenhum órgão regulador. Não é dispositivo médico.
  • É um experimento de pesquisa, com a avaliação publicada junto com o código, incluindo onde o sistema erra.
  • Nenhum caso do projeto deriva de paciente real; os exemplos são sintéticos.

A pergunta

Por que medir raciocínio clínico em português brasileiro

O gargalo de sistemas como o OpenEvidence não é o raciocínio do modelo: é o corpus licenciado (NEJM, JAMA, bases curadas próprias). Isso não se resolve com GPU melhor.

O Brasil tem uma camada de evidência normativa pública, integral e não licenciada: PCDTs, protocolos de sociedades, notas técnicas. Essas fontes estão mal representadas no treino dos modelos em inglês e não têm paywall.

E o vocabulário brasileiro não é detalhe de localização, é falha clínica mensurável. "HGT" é corrente no Brasil e rara em inglês. "Pressão" pode ser pressão arterial, aperto torácico ou peso na cabeça. Nome comercial de medicamento é outro mundo. Por isso a pergunta do projeto não é "o que ele faz?", e sim quão bem funciona, e onde falha.

Resultados da avaliação

Rodada de 2026-09-20, modelo local-model

Os gabaritos ainda não passaram por revisão clínica. Estes números medem se o pipeline funciona de ponta a ponta, não se o sistema está clinicamente correto. Não citar esta rodada como avaliação de qualidade.

Casos avaliados

8

gabaritos revisados clinicamente: 0/8

Acerto na hipótese principal

6/8

75%

Citou o documento correto

4/6

67%

Respostas sem procedência

0

precisa ser zero

Erros de execução

0

ECE (erro de calibração)

0.1750

0 = calibração perfeita

Calibração

O ECE compara a confiança declarada com a taxa real de acerto. Nesta rodada, só as respostas afirmativas (4 das 8) carregam confiança, e as barras ficaram acima da diagonal: o sistema subestimou a própria confiança. Com 4 respostas na amostra, isso é observação, não conclusão.

0.0 0.0 0.2 0.2 0.4 0.4 0.6 0.6 0.8 0.8 1.0 1.0 calibração perfeita n=1 n=3 confiança declarada acurácia real
acurácia por faixa confiança declarada ECE 0.1750. Só 4 respostas tiveram confiança; barra acima da diagonal = subestimou a confiança nesta rodada.

Caso a caso

Caso Esperado Conf. Acertou Fonte Proced.
has-001 hipertensao-arterial-sistemica -
dm2-001 diabete-melito-tipo-2 0.90
asma-001 asma 0.70
dislipidemia-001 dislipidemia 0.90
obesidade-001 sobrepeso-e-obesidade-em-adultos -
tabagismo-001 tabagismo 0.80
fora-escopo-001 nenhuma - -
ambiguidade-001 nenhuma - -

Variância entre rodadas

Três rodadas, mesma configuração (temperatura 0,1). Com 8 casos, a diferença entre rodadas é ruído.

Rodada 1 4/8 ECE 0.1833
Rodada 2 4/8 ECE 0.3333
Rodada 3 6/8 ECE 0.1750

A subida de 4/8 para 6/8 veio de consertar a métrica, não o sistema: dm2-001 e tabagismo-001 já estavam clinicamente certos, o comparador é que não os reconhecia.

Dados extraídos de resultados/avaliacao-2026-09-20.md. Reproduza com uv run raciocinio-cli avaliar.

Onde ele falha

Os erros, com a hipótese da causa

Registrar onde erra é parte do projeto, não uma fraqueza a esconder. Vem do FALHAS-CONHECIDAS.md, atualizado a cada rodada.

has-001 recuperação

Esperado: hipertensão arterial sistêmica

Para um caso de hipertensão, o FTS devolveu trechos do PCDT de Asma. O caso diz "mediu a pressão em casa e deu sempre alta"; o léxico acha o termo "pressão" isolado, marca como ambíguo e corretamente se recusa a resolver, o que deixa a consulta sem termo discriminante.

Próximo passo: Busca semântica, ou um léxico que reconheça padrões como "pressão ... alta" com palavras no meio.

obesidade-001 piso de cobertura

Esperado: sobrepeso e obesidade em adultos

O FTS trouxe o PCDT correto no topo, mas o caso é curto e o que importa está em números (98 kg, 1,62 m), não em palavras. Só 1 palavra de conteúdo em comum com o trecho, abaixo do piso de 3. Baixar o piso faria o has-001 responder sobre a diretriz errada, o pior erro aqui.

Próximo passo: O piso considerar o casamento entre a condição do trecho e os termos do caso, não só contar palavras.

tabagismo-001 modelo

Esperado: tabagismo

O FTS trouxe o PCDT de Tabagismo no topo, o piso passou, o LLM recebeu os trechos certos e devolveu hipóteses vazias. Não é falha de recuperação nem de léxico.

Próximo passo: Inspecionar a resposta crua do modelo: pode ser o prompt lido como "não afirme sem certeza" com rigor excessivo.

dm2-001 métrica, não o sistema

Esperado: diabetes mellitus tipo 2

Respondeu "Diagnóstico de Diabete Melito Tipo 2", clinicamente correto e com a grafia do próprio PCDT. O comparador não casou "mellitus" com "melito" e marcou como erro. É exatamente o eixo de vocabulário brasileiro que o projeto existe para medir, e a primeira vítima dele foi a própria métrica.

Próximo passo: Corrigido: as grafias do documento entraram em hipoteses_aceitaveis.

Dos quatro erros da primeira rodada, dois eram da métrica, não do sistema, e os dois no eixo de vocabulário brasileiro. Num projeto cujo valor é a avaliação, a métrica precisa ser testada com o mesmo rigor do resto.

O léxico brasileiro

Um artefato de valor próprio, versionado

O mapeamento curado de termos (dados/lexico-br.yaml, versão 0.1.0, revisão clínica pendente) pode ser usado independentemente do resto do projeto. Termo ambíguo nunca é normalizado em silêncio: o normalizador devolve as leituras e deixa a escolha para quem usa.

Direto

pressão alta hipertensão arterial sintoma
açúcar no sangue glicemia exame
falta de ar dispneia sintoma
chiado no peito sibilância sintoma

Ambíguo (não resolve sozinho)

pressão AMBIGUO
pressão arterialsensação de aperto torácicocefaleia em peso
cansaço AMBIGUO
dispneia aos esforçosfadigasonolência

Como fica no arquivo

- termo_popular: pressão
  termo_tecnico: AMBIGUO
  tipo: sintoma
  observacao: >-
    Ambíguo de propósito: pode ser pressão arterial,
    sensação de aperto no peito ou peso na cabeça.
    O normalizador devolve as leituras, não escolhe.
  leituras:
    - pressão arterial
    - sensação de aperto torácico
    - cefaleia em peso
  revisado: false
Trecho real de dados/lexico-br.yaml

Escopo coberto

Seis condições de medicina de família, e só

Cada uma com a diretriz de referência da Conitec. Fora deste escopo o sistema deve responder "fora do escopo": isso é decisão de design, não limitação temporária. O CID-10 principal fica pendente de decisão clínica.

Hipertensão Arterial Sistêmica

PCDT HAS

Portaria SECTICS/MS nº 49, 2025

vigente

Diabete Melito Tipo 2

PCDT DM2

Portaria SCTIE/MS nº 13/2026

em atualização

Asma

PCDT Asma

Portaria Conjunta nº 43, 2026

vigente

Dislipidemia

PCDT Dislipidemia

Portaria Conjunta nº 8, 2019

em atualização

Sobrepeso e Obesidade em Adultos

PCDT Sobrepeso e Obesidade

Portaria SCTIE/MS nº 53, 2020

vigente

Tabagismo

PCDT Tabagismo

Portaria Conjunta nº 10, 2020

vigente

Como funciona

Do texto livre à hipótese com procedência

  1. 01

    Léxico

    Normaliza o vocabulário brasileiro do caso. Termo ambíguo é devolvido com as leituras, sem escolher.

  2. 02

    Recuperação

    Busca full-text (DuckDB) na base de evidência dos PCDTs, com um piso de cobertura que decide se a pergunta está no escopo.

  3. 03

    LLM local

    O modelo raciocina sobre os trechos recuperados, na sua máquina.

  4. 04

    Estruturação com procedência

    Cada hipótese sai com citação literal, se a citação confere no documento, a confiança, e a lista do que ficou indeterminado.

Uma resposta confiante sem procedência é tratada como bug, não como estilo: o modelo de saída recusa hipótese com confiança acima de 0,5 sem trecho-fonte, e o pipeline rebaixa a confiança do que for afirmado sem origem, registrando o rebaixamento em indeterminados.

raciocinar_caso

hipóteses com procedência, conduta, termos normalizados e indeterminados. Nenhum campo é opcional.

normalizar_termo

o que o léxico entende do termo; ambíguo volta com as leituras, sem escolha.

explicar_cobertura

o que a base cobre, para saber se a pergunta está no escopo antes de confiar na resposta.

Como rodar

Reproduza a avaliação, não só use a ferramenta

Quem clona este projeto deveria conseguir rodar o mesmo harness de avaliação que gerou os números acima, não apenas ligar o servidor. Precisa de Python 3.12+, uv e um LLM local com API compatível com a da OpenAI.

# 1. clonar e instalar
git clone https://github.com/fabianofilho/raciocinio-br-mcp.git
cd raciocinio-br-mcp
uv sync
cp .env.example .env

# 2. apontar o .env para o seu LLM local e conferir
uv run raciocinio-cli llm

# 3. montar a base de evidência (baixa e indexa as diretrizes, ~1 min)
uv run raciocinio-cli coletar

# 4. reproduzir a AVALIAÇÃO (roda os casos e gera o relatório)
uv run raciocinio-cli avaliar

# 5. subir o servidor MCP e conectar ao seu cliente
uv run raciocinio-br-mcp
Confira variáveis e opções no README do projeto.

O caso que você digita vai para o seu LLM local e para a base local. O que sai da máquina é só o download das diretrizes públicas do gov.br/conitec. Sem telemetria. Atenção: se o seu endpoint de LLM apontar para fora da máquina, o caso vai junto, o projeto não impede isso.