# AI 代理和医疗数据

> AI 代理对患者记录的受控访问：OAuth 范围、代理所需的工具、其读写内容的审计和溯源，以及事件驱动的代理。

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

**AI 代理是一种程序，其中语言模型会逐步决定要执行的操作——读取哪些数据、调用哪个工具、写入什么内容——以完成任务。** 当任务涉及患者的病历时，代理需要受控访问：它应该只访问它被允许访问的记录，只访问其中的必要部分，并留下其读取内容的痕迹，同时将其写入的内容标记为 AI 生成。Anpheros 通过其 API 提供这种受控访问；代理框架和模型由您自行决定。

Anpheros 没有内置的代理运行时、Model Context Protocol (MCP) 服务器，也没有与任何代理框架或模型提供商的官方集成。代理通过 REST 和 FHIR API 或 SDK 以任何应用程序的方式使用它。

## 架构

```
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
```

模型提出操作；您的运行时使用其持有的凭证来执行这些操作。模型本身从不持有 Anpheros 密钥或令牌。

## 受控访问

- **谁的记录。** 使用 API 密钥，代理可以看到您的项目创建的患者。要操作某人现有的记录，需要获得该人员的 OAuth 授权 — 针对一个患者，有效期为 30 至 365 天。
- **哪些数据。** 范围限制了资源类型和操作，还可以选择性地限制到某个类别：`patient/Observation.rs?category=laboratory` 允许代理读取和搜索实验室结果，除此之外不能执行其他操作。要构建上下文，授权必须允许读取观察结果、状况、药物和过敏症（例如 `patient/*.rs`）。
- **默认只读。** 仅当代理需要记录某些内容时，才授予写入范围。
- **可撤销。** 该人员可以随时撤销授权；代理的下一次调用将被拒绝。

## 代理通常需要的工具

| 工具 | Anpheros 调用 | 备注 |
|---|---|---|
| 获取任务上下文 | `POST /v1/context` | 大多数任务的首次调用；已预算并标记来源 ([LLM applications and healthcare data](https://developers.anpheros.com/zh/guides/llm-healthcare-data)) |
| 列出最近的结果 | `GET /v1/patients/{id}/observations?category=laboratory&from=…` | 过滤器：`category`、`code`、`from`、`to` |
| 当前用药 | `GET /v1/patients/{id}/medications?status=active` | |
| 发生的事情 | `GET /v1/patients/{id}/timeline?from=…` | 按时间顺序跨类型的列表 |
| FHIR 完整详情 | `GET /fhir/R4/{type}?patient=…` | 当摘要不足时 |
| 标准摘要 | `GET /fhir/R4/Patient/{id}/$summary` | International Patient Summary bundle |
| 查找代码 | `GET /v1/terminology/loinc?q=…` | 已捆绑的 LOINC 子集；通过 `GET /v1/search` 查询药品 |
| 记录笔记 | `POST /v1/patients/{id}/observations` 和 `author_type: "ai"` | 仅在具有写入权限时 |

OpenAPI 规范 (`https://developers.anpheros.com/openapi.json`) 描述了每个端点，可以将其转换为工具定义；TypeScript 和 Dart SDK 可以直接包装成工具。

## 示例：带有患者同意的就诊准备代理

一位已在 Anpheros 中保留记录的患者请求第三方助手为心脏病就诊准备问题。该代理需要有限时间的读取访问权限，仅此而已。

**1. 同意（OAuth 2.1 + PKCE, SMART v2 范围）。** 助手将用户引导至同意页面，该页面具有允许上下文（观察、状况、药物和过敏）的最窄范围：

```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. 工具。** 代理运行时向模型公开了几个函数；每个函数都是使用访问令牌进行的真实 API 调用：

```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 }),
};
```

使用您的模型 API 所使用的任何工具或函数调用格式将它们描述给模型；模型会建议一个调用，您的运行时会执行它并返回 JSON。模型永远不会看到令牌。

**3. 平台强制执行的内容。** 令牌仅能访问该用户的记录以及仅限范围内的类型；任何其他内容都会返回 `403`（范围外的类型）或 `404`（另一位用户）。每次调用——包括每次上下文请求，以及其 `manifest_id`——都会出现在该用户的此应用程序访问日志中。如果用户撤销访问权限，下一次调用将返回 `401`，代理必须停止；刷新令牌无法恢复访问。

**4. 输出。** 代理返回医生的问题以及它使用的来源。它不会写回任何内容，因为它没有被授予写入范围。

## 审计和来源追溯

- 代理程序进行的每一次调用都是对记录的访问，并会出现在您应用程序的患者访问日志中 — 包括每一次上下文请求，该请求还会存储所使用的部分和来源的清单。
- 代理程序写入的所有内容都会在 `Provenance` 中记录为 AI 生成。当稍后构建上下文时，AI 生成的值会列在 `ai_notes` 下，与临床事实分开，这样代理程序就不会将自己早期生成的输出作为证据引用。

## 从事件启动代理

Webhook 允许代理在发生变化时运行——例如新的实验室结果 (`resource.created`) 或新的同意书 (`consent.granted`)——而不是轮询。事件仅包含 ID；然后代理会读取其作用域允许的内容。[Webhook](https://developers.anpheros.com/zh/guides/webhooks)

## 值得遵循的设计规则

1.  为代理提供完成任务所需的最窄范围。
2.  从上下文开始，而不是从原始批量读取开始；尊重 `omitted` 和 `warnings`。
3.  在代理的回答中显示患者的数据来源。
4.  绝不允许代理自行做出诊断或更改治疗方案；将此类输出路由给临床医生。
5.  将每个上下文的 `manifest_id` 记录在代理回答旁边，以便日后人员可以查看回答的依据。

## 相关资源

- [如何授予 AI 代理访问医疗记录的权限](https://developers.anpheros.com/zh/guides/ai-agent-access-medical-records)：Python 分步教程
- [用于 AI 代理的 FHIR MCP 服务器](https://developers.anpheros.com/zh/guides/mcp)
- [AI 医疗应用](https://developers.anpheros.com/zh/guides/ai-healthcare)
- [LLM 应用与医疗数据](https://developers.anpheros.com/zh/guides/llm-healthcare-data)
- [如何使用结构化数据构建医疗聊天机器人](https://developers.anpheros.com/zh/guides/ai-medical-assistant)
- [同意与访问模型](https://developers.anpheros.com/zh/guides/consent)
- [身份验证与 OAuth](https://developers.anpheros.com/zh/guides/authentication)
- [面向医疗应用和 AI 代理的药物数据](https://developers.anpheros.com/zh/guides/medication-data-ai-agents)：患者列表 vs 药物知识源
