# Agentes de IA y datos médicos

> Acceso controlado para agentes de IA a registros de pacientes: ámbitos de OAuth, las herramientas que un agente necesita, auditoría y procedencia de lo que lee y escribe, y agentes impulsados por eventos.

Source: https://developers.anpheros.com/es/guides/ai-agents-medical-data

**Un agente de IA es un programa en el que un modelo de lenguaje decide, paso a paso, qué acciones tomar —qué datos leer, qué herramienta llamar, qué escribir— para completar una tarea.** Cuando la tarea involucra el registro médico de un paciente, el agente necesita acceso controlado: solo debe acceder a los registros que tiene permiso para ver, solo las partes de ellos que necesita, dejar un rastro de lo que leyó y marcar lo que escribió como generado por IA. Anpheros proporciona ese acceso controlado a través de su API; el framework del agente y el modelo son suyos.

Anpheros no tiene un runtime de agente integrado, ni un servidor de Model Context Protocol (MCP), ni una integración oficial con ningún framework de agente o proveedor de modelos. Los agentes lo utilizan de la misma manera que cualquier aplicación: a través de la API REST y FHIR o los SDK.

## La arquitectura

```
Patient ── grants access (OAuth scopes, duration) ────────────────┐
                                                                  ▼
Agent runtime (your code, any framework) ── tools ──► Anpheros API ──► the patient's FHIR record
      │   ▲                                   │
      │   └── context, search results ◄───────┘      every call: scope checks + access log
      ▼
The model you choose (hosted or local) ── plans the next step
```

El modelo propone acciones; tu runtime las ejecuta con la credencial que posee. El modelo en sí nunca posee una clave o token de Anpheros.

## Acceso controlado

- **Registros de quién.** Con una API key, el agente ve los pacientes que creó tu proyecto. Para actuar sobre el registro existente de alguien, necesita una concesión OAuth de esa persona, para un paciente, durante 30 a 365 días.
- **Qué datos.** Los ámbitos (scopes) limitan los tipos de recursos y acciones, opcionalmente a una categoría: `patient/Observation.rs?category=laboratory` permite a un agente leer y buscar resultados de laboratorio y nada más. Para construir un contexto, la concesión debe permitir leer observaciones, condiciones, medicamentos y alergias (por ejemplo, `patient/*.rs`).
- **Solo lectura por defecto.** Concede ámbitos de escritura (write scopes) solo cuando el agente está destinado a registrar algo.
- **Revocable.** La persona puede revocar la concesión en cualquier momento; la siguiente llamada del agente será rechazada.

## Herramientas que un agente suele necesitar

| Herramienta | Llamada a Anpheros | Notas |
|---|---|---|
| Obtener contexto para una tarea | `POST /v1/context` | la primera llamada para la mayoría de las tareas; presupuestada y etiquetada por origen ([LLM applications and healthcare data](https://developers.anpheros.com/es/guides/llm-healthcare-data)) |
| Listar resultados recientes | `GET /v1/patients/{id}/observations?category=laboratory&from=…` | filtros: `category`, `code`, `from`, `to` |
| Medicamentos activos | `GET /v1/patients/{id}/medications?status=active` | |
| Qué sucedió cuándo | `GET /v1/patients/{id}/timeline?from=…` | una lista cronológica entre tipos |
| Detalle completo de FHIR | `GET /fhir/R4/{type}?patient=…` | cuando un resumen no es suficiente |
| Un resumen estándar | `GET /fhir/R4/Patient/{id}/$summary` | International Patient Summary bundle |
| Buscar un código | `GET /v1/terminology/loinc?q=…` | subconjunto de LOINC empaquetado; medicamentos a través de `GET /v1/search` |
| Registrar una nota | `POST /v1/patients/{id}/observations` con `author_type: "ai"` | solo con un ámbito de escritura |

La especificación OpenAPI (`https://developers.anpheros.com/openapi.json`) describe cada endpoint y puede convertirse en definiciones de herramientas; los SDK de TypeScript y Dart pueden empaquetarse directamente como herramientas.

## Ejemplo: un agente de preparación de visitas con el consentimiento del paciente

Un paciente que ya tiene un registro en Anpheros solicita a un asistente de terceros que prepare preguntas para una visita de cardiología. El agente necesita acceso de lectura al registro por un tiempo limitado, nada más.

**1. Consentimiento (OAuth 2.1 + PKCE, ámbitos SMART v2).** El asistente dirige a la persona a la página de consentimiento con los ámbitos más restrictivos que aún permiten un contexto (observaciones, condiciones, medicamentos y alergias):

```ts
import { Anpheros, OAuthAuth, OAuthFlow, generatePkce } from '@anpheros/sdk';

const flow = new OAuthFlow({ baseUrl: 'https://platform.anpheros.com', clientId: CLIENT_ID, redirectUri: REDIRECT_URI });
const pkce = await generatePkce();
const url = flow.authorizeUrl({
  scopes: ['patient/Observation.rs', 'patient/Condition.rs', 'patient/MedicationStatement.rs',
           'patient/AllergyIntolerance.rs', 'offline_access'],
  state, pkce, purpose: 'treatment',
});
// … the person chooses the record and the duration (30–365 days) and allows; on the callback:
const tokens = await flow.exchange(code, pkce);
const anpheros = new Anpheros({ auth: new OAuthAuth({ tokens, onRefresh: flow.refresh }) });
const patient = tokens.patient!;   // this application's own (pairwise) id for the person
```

**2. Herramientas.** El tiempo de ejecución del agente expone algunas funciones al modelo; cada una es una llamada API real realizada con el token de acceso:

```ts
const tools = {
  // POST /v1/context — relevant sections, within a budget, labelled with author type and source
  get_context: (a: { question: string }) =>
    anpheros.context.build({ patient, task: 'prepare a cardiology visit', question: a.question, budget_tokens: 2000, format: 'text' }),
  // GET /v1/patients/{id}/observations?category=laboratory&code=…&from=…
  list_lab_results: (a: { code?: string; from?: string }) =>
    anpheros.observations.list(patient, { category: 'laboratory', code: a.code, from: a.from, limit: 20 }),
  // GET /v1/patients/{id}/timeline?from=…
  get_timeline: (a: { from: string }) => anpheros.timeline.list(patient, { from: a.from, limit: 50 }),
};
```

Descríbalas al modelo en el formato de llamada a herramienta o función que utilice la API de su modelo; el modelo propone una llamada, su tiempo de ejecución la ejecuta y devuelve el JSON. El modelo nunca ve el token.

**3. Lo que aplica la plataforma.** El token solo llega al registro de esa persona y solo a los tipos definidos en los ámbitos; cualquier otra cosa responde con `403` (un tipo fuera de los ámbitos) o `404` (otro paciente). Cada llamada, incluida cada solicitud de contexto con su `manifest_id`, aparece en el registro de acceso de la persona para esta aplicación. Si la persona revoca el acceso, la siguiente llamada responde con `401` y el agente debe detenerse; el token de actualización no puede recuperarlo.

**4. Salida.** El agente devuelve preguntas para el médico con las fuentes que utilizó. No escribe nada, porque no se le otorgó un ámbito de escritura.

## Auditoría y procedencia

- Cada llamada que realiza el agente es un acceso al registro y aparece en el registro de acceso del paciente para su aplicación, incluyendo cada solicitud de contexto, que también almacena un manifiesto de las secciones y fuentes utilizadas.
- Todo lo que el agente escribe se registra como escrito por IA en `Provenance`. Cuando se construye un contexto posteriormente, los valores escritos por IA se enumeran en `ai_notes`, aparte de los hechos clínicos, para que un agente no termine citando su propia salida anterior como evidencia.

## Inicio de agentes a partir de eventos

Los webhooks permiten que un agente se ejecute cuando algo cambia — un nuevo resultado de laboratorio (`resource.created`), un nuevo consentimiento (`consent.granted`) — en lugar de hacer polling. Los eventos solo llevan IDs; el agente luego lee lo que sus ámbitos permiten. [Webhooks](https://developers.anpheros.com/es/guides/webhooks)

## Reglas de diseño que vale la pena seguir

1. Otorga al agente los alcances más estrechos que completen la tarea.
2. Comienza desde un contexto, no desde lecturas masivas en bruto; respeta `omitted` y `warnings`.
3. Muestra las fuentes de datos del paciente en la respuesta del agente.
4. Nunca permitas que el agente presente un diagnóstico o cambie un tratamiento por sí solo; dirige dichas salidas a un clínico.
5. Registra el `manifest_id` de cada contexto junto a la respuesta del agente, para que una persona pueda ver posteriormente en qué se basó la respuesta.

## Relacionado

- [Cómo dar acceso a un agente de IA a registros médicos](https://developers.anpheros.com/es/guides/ai-agent-access-medical-records): tutorial paso a paso en Python
- [Servidor FHIR MCP para agentes de IA](https://developers.anpheros.com/es/guides/mcp)
- [Aplicaciones de IA en salud](https://developers.anpheros.com/es/guides/ai-healthcare)
- [Aplicaciones de LLM y datos de salud](https://developers.anpheros.com/es/guides/llm-healthcare-data)
- [Cómo crear un chatbot médico con datos estructurados](https://developers.anpheros.com/es/guides/ai-medical-assistant)
- [Modelo de consentimiento y acceso](https://developers.anpheros.com/es/guides/consent)
- [Autenticación y OAuth](https://developers.anpheros.com/es/guides/authentication)
- [Datos de medicación para aplicaciones de salud y agentes de IA](https://developers.anpheros.com/es/guides/medication-data-ai-agents): la lista del paciente frente a las fuentes de conocimiento sobre fármacos
