Jamorham
Nightscout용 xDrip+ 버전
다국어(ES/EN/AR/FR) 환자 지원 도우미, 환자 검색·예약·알림·자동 메시지 제공, 합성 데이터 데모
Asistente multilingüe (ES/EN/AR/FR) para equipos de atención al paciente internacional: búsqueda de pacientes, citas, avisos y mensajes automáticos. Demo con datos sintéticos.
건강JavaScript · PythonGitHub @bfir온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Copiloto interno multilingüe (ES · EN · AR · FR) para el equipo de Atención al Paciente Internacional de un hospital. Anisa no es una app para pacientes: es una herramienta de trabajo para el personal administrativo que gestiona pacientes internacionales. Les ayuda a resolver, en lenguaje natural, tareas hoy manuales y repetitivas: localizar a un paciente, consultar sus citas, detectar pagos pendientes y preparar y enviar recordatorios en el idioma de cada paciente. Estado: demo funcional, desplegada · Datos 100 % sintéticos — ningún dato real de pacientes.README 전문 보기 ↗
Copiloto interno multilingüe (ES · EN · AR · FR) para el equipo de Atención al Paciente Internacional de un hospital.
Anisa no es una app para pacientes: es una herramienta de trabajo para el personal administrativo que gestiona pacientes internacionales. Les ayuda a resolver, en lenguaje natural, tareas hoy manuales y repetitivas: localizar a un paciente, consultar sus citas, detectar pagos pendientes y preparar y enviar recordatorios en el idioma de cada paciente.
Estado: demo funcional, desplegada · Datos 100 % sintéticos — ningún dato real de pacientes.
La API está en el plan gratuito de Render y "duerme" tras un rato de inactividad — la primera petición puede tardar ~50 segundos en responder mientras arranca.
Credenciales de prueba: [email protected] / coord123.
El rol coordinador puede usar el asistente, enviar mensajes y modificar citas. El rol
admin (que además accede al registro de auditoría) no tiene credenciales públicas: su
contraseña se define con la variable de entorno ADMIN_PASSWORD al generar los datos.
En un servicio de pacientes internacionales, el personal gestiona a diario:
Todo repartido entre varias herramientas y hojas de cálculo, y con tiempos de respuesta ajustados.
React (Vercel) ──HTTP + JWT──▶ FastAPI (api/main.py) ──▶ Postgres (Supabase)
│ ▲
▼ │ pgvector
Asistente (api/agente.py) ──▶ Groq (LLM, tool calling)
│ │
▼ │
Resend (correo real) + tabla auditoria
│
▼
consultar_documentacion ──▶ Cohere (embeddings) ──▶ documento_chunks
Cliente MCP (Claude Desktop, Inspector...) ──stdio──▶ mcp_server.py ──▶ misma Postgres (solo lectura)
El asistente es un agente: un modelo de lenguaje (vía Groq) interpreta la petición del usuario y decide qué herramientas ejecutar (buscar en la base de datos, consultar citas, redactar y enviar un mensaje, modificar una cita...), encadena los pasos necesarios y devuelve el resultado. El bucle tiene un límite de pasos y captura errores de cada herramienta para no romper la petición si algo falla a mitad de camino.
| Capa | Tecnología |
|---|---|
| Frontend | React + Vite + React Router + Tailwind CSS v4 |
| API | FastAPI + Pydantic |
| Autenticación | JWT (PyJWT) + contraseñas con argon2 (passlib) |
| Base de datos | PostgreSQL (Supabase) vía SQLAlchemy, migraciones con Alembic |
| Asistente | Groq (LLM) con tool calling escrito a mano |
| Correo | Resend (envío real, en modo sandbox a una única bandeja de pruebas) |
| RAG | Cohere (embed-multilingual-v3.0, API alojada) + pgvector (extensión de Postgres) |
| Integración | Servidor MCP (SDK oficial de Python) |
| Tests | pytest |
| Despliegue | Render (API) + Vercel (frontend) + Supabase (base de datos) |
git clone https://github.com/bfir/anisa.git
cd anisa
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt
Crea un archivo .env en la raíz con:
DATABASE_URL=postgresql://...tu-conexión-a-supabase...
GROQ_API_KEY=tu_clave
SECRET_KEY=una_cadena_aleatoria_larga
RESEND_API_KEY=tu_clave
EMAIL_DEMO_DESTINO=tu_email_de_pruebas
ADMIN_PASSWORD=una_contraseña_segura
Aplica las migraciones (crea/actualiza las tablas en tu base):
alembic upgrade head
Genera los datos sintéticos (pacientes, citas, pagos, usuarios demo). Los scripts de
scripts/ (y los tests) necesitan además las dependencias de desarrollo:
pip install -r requirements-dev.txt
python -m scripts.generar_datos
Para cambiar solo la contraseña de admin sin regenerar los datos (usa ADMIN_PASSWORD del .env):
python -m scripts.cambiar_password_admin
Arranca la API:
uvicorn api.main:app --reload
La API estará en http://localhost:8000/docs.
El esquema ya no se crea solo (Base.metadata.create_all se retiró): cualquier cambio a
api/models_orm.py necesita su migración explícita.
# después de cambiar un modelo en api/models_orm.py
alembic revision --autogenerate -m "descripción del cambio"
# revisa el archivo generado en alembic/versions/ antes de aplicarlo
alembic upgrade head
alembic/env.py toma DATABASE_URL de .env — no hay ninguna contraseña en alembic.ini ni en
el repo.
cd frontend
npm install
Crea frontend/.env con:
VITE_API_URL=http://localhost:8000
npm run dev
El panel estará en http://localhost:5173.
El asistente tiene una herramienta de solo lectura, consultar_documentacion, que busca
semánticamente (no por palabras clave) en 7 documentos sintéticos de políticas de aseguradoras
(data/documentos/). Cada pregunta se compara contra fragmentos ya convertidos en vectores
(embeddings) guardados en Postgres con pgvector, y el asistente cita siempre el documento y la
sección de donde sale la información.
Se probó primero con un modelo local (sentence-transformers, multilingüe) y se midió su coste
real antes de decidir: 627 MB de RAM solo por tenerlo cargado, por encima del límite de
512 MB del plan gratuito de Render. Se sustituyó por la API alojada de Cohere
(embed-multilingual-v3.0), que no consume memoria en el propio servicio.
Evaluación (pytest tests/), sobre 20 preguntas con respuesta de referencia marcada a mano,
2 de ellas deliberadamente sin respuesta para comprobar que el asistente no se la inventa:
| Métrica | Resultado |
|---|---|
| Recall@5 de la recuperación | 100 % (18/18 preguntas con respuesta real) |
| Fidelidad (todo lo dicho está en el contexto recuperado, juzgado por un LLM) | 17-19/20 según la tanda* |
| Corrección (coincide con la respuesta de referencia, juzgado por un LLM) | 19-20/20 según la tanda* |
| Recuperación vectorial vs. híbrida (vector + BM25, comparadas con datos) | Empate 100 % en recall@1/3/5 — se mantiene la vectorial por ser más simple |
* El asistente no usa temperature=0, así que el resultado exacto varía ligeramente entre
ejecuciones; siempre se ha mantenido por encima del umbral de aceptación (80 % y 70 % respectivamente).
Latencia medida (llamando al servidor MCP como lo haría un cliente real, sesión ya iniciada):
buscar_docs: ~3.6 s por consulta — dominado por la llamada de red a la API de Cohere.consultar_auditoria: ~0.1-0.4 s por consulta — es solo una consulta SQL, sin llamada externa.Coste medido (no estimado a ojo — verificado contra la página de precios de Cohere a fecha de
este commit): embed-multilingual-v3.0 cuesta 0,10 $ por millón de tokens de entrada. Una
pregunta típica (~25 tokens) cuesta por tanto unos 0,0000025 $ — en la práctica, gratis a esta
escala; a un millón de preguntas, costaría unos 2,50 $. consultar_auditoria no tiene coste de
API, solo el coste fijo ya existente de Supabase.
Además del asistente conversacional, los mismos datos de solo lectura se exponen por
MCP (mcp_server.py), el protocolo abierto para conectar
herramientas a clientes de IA de forma estandarizada — así Claude Desktop, el MCP Inspector, o
cualquier otro cliente compatible, pueden usarlos sin pasar por el asistente de Anisa. Expone dos
herramientas, ambas de solo lectura (nunca envían mensajes ni modifican citas):
buscar_docs(pregunta) — igual que la herramienta del asistente, busca en la documentación de
aseguradoras.consultar_auditoria(filtro) — busca en el historial de preguntas ya hechas al asistente, por
texto contenido en la pregunta o la respuesta.Probarlo con el Inspector visual (requiere Node.js, ya instalado en este equipo):
mcp dev mcp_server.py
Abre una interfaz web donde se pueden listar y ejecutar las herramientas a mano.
Probarlo como lo haría un cliente real, sin interfaz gráfica (así se verificó en el desarrollo):
un cliente MCP en Python (mcp.client.stdio.stdio_client + mcp.ClientSession) que arranca
mcp_server.py como subproceso, llama a list_tools() y a call_tool(...), y lee la respuesta.
Conectarlo a Claude Desktop: añadir en su claude_desktop_config.json:
{
"mcpServers": {
"anisa": {
"command": "python",
"args": ["C:/Users/bfir2/proyectos/anisa/mcp_server.py"]
}
}
}
Limitación honesta: este servidor MCP, igual que la API de FastAPI en su endpoint raíz, no tiene autenticación — cualquiera que lo ejecute en su máquina puede llamarlo. Es aceptable porque todo son datos sintéticos, pero en un sistema real habría que añadir verificación de token, como ya tiene el resto de la API.
Este es un proyecto de portfolio en construcción activa. Con honestidad sobre lo que falta:
El asistente prepara propuestas para enviar mensajes o modificar citas. No ejecuta estas acciones durante una pregunta: el operador revisa el paciente, texto o cita y pulsa «Aprobar y ejecutar» o «Descartar». Las propuestas se conservan en auditoría, pertenecen al usuario que las solicita y caducan a los 15 minutos.
La aprobación reserva la propuesta antes de ejecutar para impedir reenvíos por doble clic o repetición de la petición. Una propuesta en curso cuyo resultado no se haya confirmado debe revisarse antes de solicitar otra. Los cambios de cita comprueban que la cita sigue igual que cuando se propuso. El correo mantiene el destino de pruebas de la demo.
API: GET /agente/acciones, GET /agente/acciones/{id} y
POST /agente/acciones/{id} con {"decision": "aprobar"} o
{"decision": "rechazar"}. Todas requieren un operador autenticado.
Proyecto formativo y de portfolio. Todos los datos son ficticios y generados automáticamente. Anisa no se conecta a ningún sistema hospitalario real ni procesa información real de pacientes.
MIT © 2026 Firdaous Boulahfa El Mourabit