Resolver procedimento por nome¶
Transforma o nome do exame/consulta em linguagem natural em um
(id_procedimento, id_especialidade, id_agenda).
Complexidade crescente¶
Dependendo da clínica, a dificuldade muda:
- MEDCENTER: 1 procedimento por médico (consulta da especialidade dele). Basta resolver médico → procedimento cai junto.
- CLINFETO: ~100+ procedimentos, múltiplos médicos podem fazer o mesmo.
Caso simples — Medcenter¶
# scheduling.py (MEDCENTER)
PROCEDIMENTOS = [
{"id_especialidade": 450, "id_agenda": 3, "id_procedimento": 64639,
"procedimento": "CONSULTA ORTOPEDISTA MAURICIO",
"medico": "MAURICIO SIQUEIRA CAMILO"},
# ... 7 médicos
]
# Resolve tudo pelo médico
def buscar_procedimento_por_medico(nome_medico: str) -> dict | None:
# ... ver resolver-medico.md
O nome do procedimento é praticamente ignorado — o que importa é o médico.
Caso complexo — Clinfeto¶
Estrutura de dados¶
# agendamento.py:73-202 (CLINFETO)
PROCEDIMENTOS_JOANA = {
167: (58, 129, "US ABDOME INFERIOR MASCULINO"),
168: (58, 129, "US ABDOME SUPERIOR"),
170: (58, 129, "US ABDOME TOTAL"),
# ... ~100 procedimentos
}
PROCEDIMENTOS_RENNAN = { ... }
PROCEDIMENTOS_OB = { ... } # obstetrícia compartilhada entre 3 médicas
PROCEDIMENTOS_POR_AGENDA = {
58: PROCEDIMENTOS_JOANA,
57: PROCEDIMENTOS_SUELEM,
55: PROCEDIMENTOS_RAFAELLA,
54: PROCEDIMENTOS_PRISCILA,
59: PROCEDIMENTOS_RENNAN,
}
Cada entrada é id_procedimento → (id_agenda, id_especialidade, nome_canônico).
Busca por nome + agenda¶
def buscar_procedimento(nome_procedimento: str, agenda_id: int) -> dict | None:
procs = PROCEDIMENTOS_POR_AGENDA.get(agenda_id, {})
norm = _normalize(apply_aliases(_normalize(nome_procedimento)))
# Exato
for pid, (aid, eid, nome) in procs.items():
if _normalize(nome) == norm:
return {"id_agenda": aid, "id_especialidade": eid, "id_procedimento": pid}
# Parcial
for pid, (aid, eid, nome) in procs.items():
nn = _normalize(nome)
if norm in nn or nn in norm:
return {"id_agenda": aid, "id_especialidade": eid, "id_procedimento": pid}
return None
Aliases — acomodar variações do LLM¶
O LLM produz variações ("ULTRASSOM ABDOMINAL", "US ABDOME TOTAL", "ultrassonografia de abdômen"). Use um dicionário explícito:
# agendamento.py:205-292 (CLINFETO, trecho)
ALIASES = {
"OBSTETRICA INICIAL ENDOVAGINAL": "US OBSTETRICA (ENDOVAGINAL)",
"OBSTETRICA ENDOVAGINAL": "US OBSTETRICA (ENDOVAGINAL)",
"MORFOLOGICA 1 TRIMESTRE": "US OBSTETRICA MORFOLOGICA 1 TRIMESTRE",
"TRANSVAGINAL": "US TRANSVAGINAL (UTERO OVARIO ANEXOS E VAGINA)",
"MAMA": "US MAMA / AXILA",
"ABDOME TOTAL": "US ABDOME TOTAL",
# ... ~100 aliases
}
def apply_aliases(nome_normalizado: str) -> str:
return ALIASES.get(nome_normalizado, nome_normalizado)
Origem dos aliases
Cada alias veio de um caso real onde o LLM errou. Não é preventivo, é corretivo. Quando adicionar um novo alias, documentar o motivo em comentário se for obscuro.
"Sem preferência de médico" — agregação¶
Se o paciente não escolheu médico, precisamos saber quais médicos fazem o procedimento. Solução:
def buscar_procedimentos_todos_medicos(nome_procedimento: str) -> list[dict]:
"""Retorna lista de {id_agenda, id_especialidade, id_procedimento} para
TODOS os médicos que fazem esse procedimento."""
norm = _normalize(apply_aliases(_normalize(nome_procedimento)))
result = []
for agenda_id, procs in PROCEDIMENTOS_POR_AGENDA.items():
for pid, (aid, eid, nome) in procs.items():
if _normalize(nome) == norm or norm in _normalize(nome):
result.append({
"id_agenda": aid,
"id_especialidade": eid,
"id_procedimento": pid,
})
break # um resultado por agenda
return result
O que o agente precisa saber¶
Ambos os projetos colocam a lista de procedimentos disponíveis no system prompt (ou em menus numerados). O LLM escolhe o nome da lista, o que reduz o espaço de variação.
Nunca deixar o LLM inventar nomes
Se o paciente pede "USG do pé" e a clínica não faz, o agente precisa
retornar FALHA_CONSULTA (ou transferir), nunca tentar mapear para algo
parecido.
Guardião anti-inversão¶
LLMs às vezes invertem os argumentos (nome_convenio recebe o
procedimento, nome_procedimento recebe o convênio). Ver
Guardian validator.