Executive summary
| Business problem | Coordinators lost time searching payer policies, SOPs and scheduling screens while patients waited, and answers varied from person to person. |
|---|---|
| Solution | A read-only AI agent grounded in approved policy documents, with live, identity-aware access to scheduling and referral data. |
| Platform | Microsoft Foundry Agent Service, Azure AI Search, Azure API Management, Microsoft Entra ID, Azure AI Content Safety, Application Insights. |
| Risk posture | Private networking, per-user authorization, field masking, human approval for patient messages, and a full audit trail. |
| Value levers | Faster answers, fewer denials from missed prior authorization steps, consistent answers, and quicker onboarding of new staff. |
The problem: answers buried in a hundred places
Before the agent, a coordinator handling a referral might check payer policy PDFs, clinic SOPs, the prior authorization matrix and the scheduling system—often while the patient waited on the line. The context was fragmented, the same question could produce different answers, and important steps were easy to miss during a busy shift.
The Care Navigator answers practical questions in plain language: “Does this payer need prior authorization for an outpatient MRI, and what documents go with it?”, “What is the next open cardiology slot at the Back Bay clinic, and has this referral been received?”, or “Draft a message telling the patient what to bring to their first appointment.” Every response cites the policy or system it came from. Version one only reads data; anything sent to a patient waits for a staff member to review and approve it.
Why Microsoft Foundry, not just Copilot
The key decision was to choose a platform suited to a governed, tool-using agent that needs production networking, identity and evaluation—not just a chat surface.
| Option | Good fit when | Why not for this build |
|---|---|---|
| Microsoft 365 Copilot | People need an assistant embedded in familiar Microsoft 365 apps and work content. | This workflow needs custom orchestration, controlled clinical-system tools and application-specific evaluations. |
| Copilot Studio | Teams need low-code conversational workflows, connectors and business-user extensibility. | The design calls for code-first lifecycle control, a custom retrieval pipeline and service-level integration policies. |
| Microsoft Foundry Agent Service — Chosen | Teams need a managed agent runtime with model choice, tools, evaluation and tracing. | Selected because it aligns with the required agent lifecycle and supports the chosen network and governance pattern. |
Foundry brought the core agent capabilities together: model choice from the catalog (a GPT-5-class model and text-embedding-3-large), built-in agent tools for file search, Azure AI Search, OpenAPI and MCP servers, a standard agent setup with bring-your-own VNet, and integrated evaluations, tracing and safety controls.
The architecture
Design principle: the agent reasons and retrieves, but it never becomes an authorization boundary. Entra ID establishes the user; downstream services enforce access; API Management masks fields and applies policy; and staff remain responsible for patient-facing actions.
| Layer | Service | Role |
|---|---|---|
| Experience | Microsoft Teams | Where coordinators ask questions. |
| Identity | Microsoft Entra ID | Sign-in, group-based roles and on-behalf-of tokens. |
| Agent runtime | Microsoft Foundry Agent Service | Orchestration, tool calling, threads and agent versions. |
| Models | GPT-5-class + text-embedding-3-large | Reasoning and retrieval. |
| Knowledge | Azure AI Search | Hybrid index with semantic ranking and security filters. |
| Integration | Azure API Management | MCP endpoint; token exchange, masking, quotas and logging. |
| Safety | Azure AI Content Safety | Prompt Shields for direct and indirect attacks. |
| State | Azure Cosmos DB, Azure Storage, Azure Key Vault | Threads, files and secrets behind private endpoints. |
| Observability | Application Insights, Foundry tracing | Traces, latency, tokens and continuous quality scoring. |
| Delivery | Bicep, pipelines on self-hosted runner | Repeatable dev, test and production environments. |
Anatomy of one request
- A coordinator signs in to Teams with Microsoft Entra ID and asks a question.
- Content Safety checks the input for direct prompt attacks and unsafe content.
- The model plans whether the request needs policy retrieval, a system lookup, or both.
- Azure AI Search runs a hybrid query with effective-date and group-based security filters.
- The agent calls the relevant API Management MCP operation using an on-behalf-of identity.
- API Management and the downstream service authorize the user; the gateway masks unnecessary fields.
- Prompt Shields inspect retrieved content as untrusted input before it is used in the response.
- The agent answers with citations in the coordinator’s Cosmos DB-backed thread; a patient message remains a draft until staff approval.
The build, A to Z
A. Frame the problem before writing any code
We wrote a problem contract with the intended users, supported questions, data owners, measurable outcomes and explicit non-goals. Version one is read-only: no appointment booking, referral changes or message sending. The red-team plan covered prompt injection in documents, cross-user access, stale policies, ambiguous patient matching and requests for more information than a coordinator needs.
B. Provision the Foundry resource
We chose a Standard agent setup, aligned the resource and project with the approved network design, and planned private endpoints for data and state services. Bicep provisions dev, test and production consistently. Entra roles follow least privilege: developers manage non-production resources, while the runtime receives only the permissions required for approved tools and indexes.
C. Notebook 01: connect and smoke-test
The first notebook authenticates through the developer’s configured identity and verifies that the project endpoint and model deployment are reachable. Credentials stay out of the notebook; local development uses DefaultAzureCredential, while deployed workloads use managed identity.
# 01_connect.ipynb
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
PROJECT_ENDPOINT = "https://<foundry>.services.ai.azure.com/api/projects/<project>"
project = AIProjectClient(endpoint=PROJECT_ENDPOINT, credential=DefaultAzureCredential())
client = project.get_openai_client()
r = client.responses.create(model="chat-deploy", input="Reply with OK if you can read this.")
print(r.output_text)
D. Notebook 02: ground the agent in policy documents (RAG)
Approved payer policies, SOPs and authorization matrices are normalized, chunked with source metadata and indexed in Azure AI Search. The index stores content, content_vector, title/source_url, doc_type, payer/service_line, effective_date/expiry_date and acl_groups. A hybrid text-and-vector query is combined with semantic ranking; the filter restricts results to the user’s groups and currently effective documents.
| Index field | Purpose |
|---|---|
content | Searchable text chunk from the approved source. |
content_vector | Embedding used for vector retrieval. |
title / source_url | Human-readable source identity and citation link. |
doc_type | Distinguishes payer policies, SOPs and authorization matrices. |
payer / service_line | Enables scoped retrieval for the payer and service in the question. |
effective_date / expiry_date | Supports current-policy filtering and citation freshness checks. |
acl_groups | Restricts retrieval to the caller’s authorized groups. |
filter_expr = (
f"acl_groups/any(g: search.in(g, '{','.join(user_group_ids)}')) "
f"and effective_date le {today} and (expiry_date ge {today} or expiry_date eq null)"
)
In production, group identifiers and dates are validated and safely encoded by the query layer. Each returned chunk retains its source and effective dates so citations can be checked and displayed.
E. Notebook 03: expose clinical systems as tools
Scheduling and referral data are exposed through narrowly scoped, read-only MCP operations. The gateway verifies the caller’s delegated identity, validates inputs, applies quotas, masks fields that are not needed and records an audit event.
| MCP operation | Purpose | Guardrail |
|---|---|---|
get_coverage | Look up coverage details relevant to a payer and service. | Return only the minimum coverage fields needed for the question. |
get_referral_status | Check whether a referral was received and its current status. | Require an authorized patient/referral identifier and enforce caller access. |
find_open_slots | Find available appointment slots by specialty and clinic. | Return availability only; creating or changing appointments is out of scope. |
get_patient_summary | Retrieve the limited patient context needed to coordinate a referral. | Apply field-level masking and authorization before returning results. |
The following illustrates the gateway policy shape; production policies also validate the identity provider’s claims and use environment-specific named values.
<policies>
<inbound>
<base />
<validate-jwt header-name="Authorization" failed-validation-httpcode="401">
<openid-config url="{{entra-openid-config}}" />
<required-claims>
<claim name="aud" match="all"><value>{{api-audience}}</value></claim>
</required-claims>
</validate-jwt>
<rate-limit-by-key calls="60" renewal-period="60"
counter-key="@(context.Request.IpAddress)" />
</inbound>
<backend><base /></backend>
<outbound>
<base />
<set-header name="X-Request-ID" exists-action="override">
<value>@(context.RequestId.ToString())</value>
</set-header>
</outbound>
<on-error><base /></on-error>
</policies>
F. Notebook 04: create the agent
The agent receives only the tools needed for the read-only workflow. Tool schemas constrain inputs; service-side authorization remains authoritative. The example below is a wiring sketch—the deployed project’s current SDK version and tool registration format are pinned and validated in its build.
# 04_create_agent.ipynb — illustrative tool wiring
from azure.ai.projects.models import AzureAISearchTool, MCPTool
search_tool = AzureAISearchTool(
connection_id=SEARCH_CONNECTION_ID,
index_name="care-navigation",
)
mcp_tool = MCPTool(
server_label="care-systems",
server_url=APIM_MCP_ENDPOINT,
allowed_tools=[
"get_coverage",
"get_referral_status",
"find_open_slots",
"get_patient_summary",
],
)
agent = project.agents.create_agent(
model="chat-deploy",
name="Boston HealthCare Care Navigator",
instructions=AGENT_INSTRUCTIONS,
tools=[search_tool, mcp_tool],
)
Instructions:
You are the Boston HealthCare Care Navigator for authorized coordinators.
Answer using approved, currently effective policy sources and authorized tool results.
Cite each material claim with its source and effective date. If evidence is missing,
stale, conflicting, or the caller is not authorized, say so and do not guess.
Use only read-only tools. Never book or change appointments, alter referrals, or send
patient communications. You may draft a patient message, but a staff member must
review and approve it before it is sent. Minimize patient information in every reply.
Keeping PHI safe: security, privacy and responsible AI
| Control area | Implementation approach |
|---|---|
| BAA scope | Confirm the healthcare entity’s agreements and service configuration cover every component that can process or store PHI before production use. |
| Network isolation | Use private connectivity for the agent, search, storage, Cosmos DB and Key Vault where supported; restrict public ingress and egress. |
| Identity and least privilege | Use Entra ID, delegated/on-behalf-of access, managed identities and role-specific permissions; enforce authorization in each downstream system. |
| Data minimization | Retrieve only the fields needed for the request, mask sensitive fields at the gateway, and define retention for prompts, traces and thread data. |
| Content safety | Apply Prompt Shields to user input and retrieved content, test adversarial documents and keep untrusted content separate from instructions. |
| Human in the loop | Patient-facing messages are drafts only until an authorized staff member reviews and explicitly approves them. |
Audit is built into the request path: user and tool identity, operation, timestamp, result status, source citations and approval events are correlated with a request ID. Logs are access-controlled and configured to avoid retaining unnecessary PHI.
Proving it works: evaluation, observability and go-live
- Golden question set: maintain representative payer, referral, scheduling and message-drafting questions with reviewed expected sources and outcomes.
- Foundry evaluations: score groundedness, relevance, task adherence and tool accuracy, plus a custom
cites_current_policycheck. - Access tests: verify permitted, denied and cross-group retrieval for both search results and clinical-system tools.
- Red-teaming: test prompt injection, sensitive-data extraction, stale/conflicting sources and unsafe action requests.
- Observability: correlate Foundry traces and Application Insights for tool calls, latency, token use, safety outcomes and failures.
- Staged rollout: begin with a limited coordinator cohort, review quality and access telemetry, then expand only when release gates pass.
# 06_evaluate.ipynb
from azure.ai.evaluation import (evaluate, GroundednessEvaluator, RelevanceEvaluator,
TaskAdherenceEvaluator, ToolCallAccuracyEvaluator)
result = evaluate(
data="golden_set_v3.jsonl",
evaluators={
"groundedness": GroundednessEvaluator(model_config),
"relevance": RelevanceEvaluator(model_config),
"task_adherence": TaskAdherenceEvaluator(model_config),
"tool_accuracy": ToolCallAccuracyEvaluator(model_config),
"current_policy": cites_current_policy,
},
azure_ai_project=PROJECT_ENDPOINT,
)
| Release gate | Evidence required before expansion |
|---|---|
| Groundedness and relevance | Evaluation thresholds agreed with clinical operations are met on the approved golden set. |
| Citations | Answers cite traceable, current sources; stale or missing evidence is clearly surfaced. |
| Authorization | Positive and negative user/group access tests pass for search and every tool. |
| Red-team | Critical prompt-injection, privacy and unsafe-action scenarios are mitigated and retested. |
| Performance | Latency, reliability and capacity meet the agreed service objectives under representative load. |
What changed, and what we learned
- One place to ask instead of four separate systems.
- Answers coordinators can trust, verify and show through citations.
- Fewer avoidable denials by surfacing prior authorization steps at the point of work.
- Compliance controls designed into identity, retrieval and approval—not added at the end.
- Faster ramp-up for new staff with consistent, source-backed guidance.
- A reusable platform and operating model, not a one-off chatbot.
- Start with a narrow problem contract and explicit non-goals; it makes the first safe release measurable.
- Treat authorization as an end-to-end property. A prompt cannot replace downstream access checks.
- Make freshness and provenance first-class retrieval data so citations can be evaluated, not merely displayed.
- Keep write actions separate from read workflows. Drafting is useful; sending still requires a human decision.
- Build evaluation and observability alongside the agent. Quality, safety and operational readiness are release criteria.