必应接地API
用于Azure AI代理服务的基于FastAPI的REST API和模型上下文协议(MCP)服务器,具有Bing基础功能。通过REST和MCP接口提供基于人工智能的自动引文提取响应。
特性
✅ REST API 基于Bing的Azure AI代理包装器\ ✅ 模型上下文协议(MCP)服务器 通过Azure API管理\ ✅ 带引用的结构化JSON响应\ ✅ 用于多区域部署的区域跟踪元数据\ ✅ Docker容器化,易于部署\ ✅ 健康检查端点\ ✅ Azure容器应用程序就绪\ ✅ 线程管理和清理\ ✅ APIM负载平衡与断路器模式\ ✅ 会话关联性(粘性会话)\ ✅ 自动故障转移和恢复\ ✅ 使用Azure Developer CLI(azd)自动部署\ ✅ 在配置过程中自动创建的12个AI代理\ ✅ 用于标准化AI工具集成的MCP端点
______________________________________________________________________
快速入门:配置并部署到Azure
最快的入门方法是使用Azure Developer CLI:
# 1. Login to Azure
azd auth login
# 2. Create environment (first time only)
azd env new
# 3. Provision and deploy everything
azd up就是这样! 一个命令可以完成所有事情:
- ✅ 提供所有Azure资源(容器应用程序、AI Foundry、APIM等)
- ✅ 自动创建12个基于Bing的GPT-4o AI代理(新API)
- ✅ 构建和部署Docker容器
- ✅ 配置托管身份和RBAC
- ✅ 使用负载平衡设置API管理
整个过程大约需要8-15分钟。
您的API将在输出中显示的端点处可用。
常用命令
| 命令 | 它的作用 | 何时使用 |
|---|---|---|
azd up | 提供+部署一切 | 用于初始设置和更新 |
azd deploy | 仅部署代码(跳过配置) | 快速更新现有资源的代码 |
azd down | 删除所有Azure资源 | 清理/拆除环境 |
azd env list | 显示可用环境 | 检查存在哪些环境 |
📚 有关详细的配置步骤,请参阅 部署到Azure 在......下面
💡 通过APIM连接MCP服务器:Azure API管理本机将REST API转换为模型上下文协议(MCP)服务器。MCP客户端(如GitHub Copilot、Semantic Kernel或Azure OpenAI Responses API)通过HTTP/SSE传输连接到APIM的MCP端点,以作为标准化工具访问您的API。看 APIM作为MCP服务器 了解详情。 ⚠️ 部署后需要手动执行步骤:The azd deploy postdeploy钩子将显示在APIM门户中创建MCP服务器的说明(1-2分钟)。此步骤目前是手动的,因为ARM/Diber模板中尚未提供MCP服务器资源。______________________________________________________________________
建筑
当前架构:具有代理池的单个项目
graph TB
subgraph External["External Clients"]
Client[LLM Suite / MCP Client]
end
subgraph APIM["Azure API Management"]
Gateway[API Gateway
• Circuit Breaker
• Rate Limiting
• Session Affinity]
end
subgraph ContainerApps["Container Apps Environment"]
CA1[Container App 1
12 Agent Endpoints]
CA2[Container App 2
12 Agent Endpoints]
CA3[Container App 3
12 Agent Endpoints]
end
subgraph Foundry["Azure AI Foundry (Single Project)"]
Project[AI Project]
GPT4O[GPT-4o Deployment
10K TPM Capacity]
subgraph Agents["Agent Pool (12 Agents)"]
Agent1[Agent 1]
Agent2[Agent 2]
Agent12[Agent 12]
end
Bing[Bing Grounding
Connection]
end
Client -->|HTTPS Requests| Gateway
Gateway -->|Load Balance| CA1
Gateway -->|Load Balance| CA2
Gateway -->|Load Balance| CA3
CA1 & CA2 & CA3 -->|Managed Identity| Project
Project --> Agents
Agent1 & Agent2 & Agent12 -->|Use| GPT4O
Agent1 & Agent2 & Agent12 -->|Search| Bing
style Gateway fill:#0078d4,color:#fff
style CA1 fill:#00bcf2,color:#000
style CA2 fill:#00bcf2,color:#000
style CA3 fill:#00bcf2,color:#000
style Project fill:#50e6ff,color:#000
style GPT4O fill:#ff6b6b,color:#fff
style Bing fill:#00b294,color:#fff特点:
- ✅ TPM容量: 10K TPM(在所有代理之间共享)
- ✅ 代理池: 12个负载分配代理
- ✅ 高可用性: 3个容器应用程序实例
- ✅ APIM负载平衡: 仅跨容器应用程序
- ⚠️ 单个TPM配额: 所有代理共享相同的GPT-4o部署
用例: 开发、试点项目、中等生产工作量(高达约30万次查询/月)
每月费用: 约2000美元(见 成本分析 在......下面
______________________________________________________________________
横向扩展策略
随着您的工作负载增长到超过10K TPM容量,您有几个扩展选项。每种策略在复杂性、成本和LLM Suite集成方面都有不同的权衡。
策略1:垂直规模(每个项目增加TPM)
graph TB
subgraph External["External Clients"]
Client[LLM Suite / MCP Client]
end
subgraph APIM["Azure API Management"]
Gateway[API Gateway]
end
subgraph ContainerApps["Container Apps (3 instances)"]
CA[Container Apps
12 Agent Endpoints]
end
subgraph Foundry["Azure AI Foundry (Single Project)"]
Project[AI Project]
GPT4O[GPT-4o Deployment
⬆️ 100K TPM
Provisioned Throughput]
Agents[Agent Pool
12 Agents]
Bing[Bing Grounding]
end
Client -->|HTTPS| Gateway
Gateway -->|Load Balance| CA
CA -->|Managed Identity| Project
Project --> Agents
Agents -->|Use| GPT4O
Agents -->|Search| Bing
style Gateway fill:#0078d4,color:#fff
style CA fill:#00bcf2,color:#000
style GPT4O fill:#ff6b6b,color:#fff
style Project fill:#50e6ff,color:#000实施:
- 将GPT-4o部署从10K增加到100K TPM(或更高)
- 使用预留吞吐量单位(PTU)保证容量
- 无需更改架构
特点:
- ✅ 最简单的方法 -无代码更改
- ✅ 单端点 LLM套房
- ✅ 高达1M TPM 带PTU
- ⚠️ 成本更高 -PTU定价(约540美元/PTU/月)
- ⚠️ 单点故障 (一个项目)
LLM套件集成:
- 无需更改 -相同的端点结构
- 继续使用
/bing-grounding/gpt4o_{1-12}端点
每月费用: 根据PTU分配,约为5K-50K美元
何时使用: 当您需要快速扩展而无需更改架构时
______________________________________________________________________
策略2:多项目横向规模(APIM管理)
graph TB
subgraph External["External Clients"]
Client[LLM Suite / MCP Client
Single Endpoint]
end
subgraph APIM["Azure API Management - Backend Pool"]
Gateway[API Gateway
Round-Robin LB
Circuit Breaker]
end
subgraph Backend1["Environment 1"]
CA1[Container Apps
12 Agents]
Project1[AI Project 1
GPT-4o: 10K TPM]
end
subgraph Backend2["Environment 2"]
CA2[Container Apps
12 Agents]
Project2[AI Project 2
GPT-4o: 10K TPM]
end
subgraph Backend3["Environment 3"]
CA3[Container Apps
12 Agents]
Project3[AI Project 3
GPT-4o: 10K TPM]
end
Client -->|HTTPS| Gateway
Gateway -->|Route 33%| CA1
Gateway -->|Route 33%| CA2
Gateway -->|Route 34%| CA3
CA1 --> Project1
CA2 --> Project2
CA3 --> Project3
style Gateway fill:#0078d4,color:#fff
style CA1 fill:#00bcf2,color:#000
style CA2 fill:#00bcf2,color:#000
style CA3 fill:#00bcf2,color:#000
style Project1 fill:#50e6ff,color:#000
style Project2 fill:#50e6ff,color:#000
style Project3 fill:#50e6ff,color:#000实施:
- 部署多个环境:
# Create 3 separate environments
azd env new prod-foundry-1
azd up
azd env new prod-foundry-2
azd up
azd env new prod-foundry-3
azd up- 配置APIM后端池:
https://ca-foundry1.azurecontainerapps.io
https://ca-foundry2.azurecontainerapps.io
https://ca-foundry3.azurecontainerapps.io
特点:
- ✅ 线性容量扩展 (3个项目×10K=30K TPM)
- ✅ 容错 -项目失败不会影响他人
- ✅ 成本效益 -按使用付费定价
- ✅ 单端点 用于LLM套件(APIM处理路由)
- ⚠️ 更多基础设施 管理(3个环境)
- ⚠️ 需要APIM配置 更新
LLM套件集成:
- 无需更改 -LLM套件看到单个APIM端点
- APIM透明地路由到可用的Foundry项目
- 保持不变
/bing-grounding/gpt4o_{1-12}端点结构
每月费用: 约6000美元(3个环境×每个环境2K美元)
何时使用:
- 需要20K-50K TPM容量
- 希望跨项目容错
- 相较于PTU定价,更倾向于按次付费
______________________________________________________________________
策略3:横向扩展与客户端负载平衡
graph TB
subgraph External["External Clients"]
Client[LLM Suite / MCP Client
⬆️ Client-Side LB Logic]
end
subgraph APIM["Azure API Management"]
Gateway[API Gateway
Shared Policies]
end
subgraph Backend1["Environment 1"]
CA1[Container Apps
12 Agents]
Project1[AI Project 1
GPT-4o: 10K TPM]
end
subgraph Backend2["Environment 2"]
CA2[Container Apps
12 Agents]
Project2[AI Project 2
GPT-4o: 10K TPM]
end
subgraph Backend3["Environment 3"]
CA3[Container Apps
12 Agents]
Project3[AI Project 3
GPT-4o: 10K TPM]
end
Client -->|33% Traffic| Gateway
Client -->|33% Traffic| Gateway
Client -->|34% Traffic| Gateway
Gateway -->|/project1/*| CA1
Gateway -->|/project2/*| CA2
Gateway -->|/project3/*| CA3
CA1 --> Project1
CA2 --> Project2
CA3 --> Project3
style Client fill:#ffa500,color:#fff
style Gateway fill:#0078d4,color:#fff
style CA1 fill:#00bcf2,color:#000
style CA2 fill:#00bcf2,color:#000
style CA3 fill:#00bcf2,color:#000
style Project1 fill:#50e6ff,color:#000
style Project2 fill:#50e6ff,color:#000
style Project3 fill:#50e6ff,color:#000实施:
- 使用不同的路径部署多个环境:
azd env new prod-foundry-1
azd up
# Endpoint: https://apim.azure-api.net/project1/bing-grounding
azd env new prod-foundry-2
azd up
# Endpoint: https://apim.azure-api.net/project2/bing-grounding
azd env new prod-foundry-3
azd up
# Endpoint: https://apim.azure-api.net/project3/bing-grounding- 配置APIM路由:
- 更新LLM套件配置:
# LLM Suite config
foundry_endpoints:
- url: https://apim.azure-api.net/project1/bing-grounding
weight: 33
capacity: 10000 # TPM
- url: https://apim.azure-api.net/project2/bing-grounding
weight: 33
capacity: 10000
- url: https://apim.azure-api.net/project3/bing-grounding
weight: 34
capacity: 10000
load_balancing:
strategy: round-robin # or weighted, least-connections
health_check_interval: 30s特点:
- ✅ 完全控制 LLM套件中的路由逻辑
- ✅ 项目特定路线 用于工作负载隔离
- ✅ 自定义故障转移 逻辑可能
- ✅ 成本可见性 每个项目端点
- ⚠️ LLM套件需要更改 (配置+逻辑)
- ⚠️ 复杂的 客户端实现
- ⚠️ 手动端点管理
LLM套件集成:
- 需要更改配置 -多个端点
- 需要负载平衡逻辑 -客户端循环/加权
- 建议进行健康监测 -检查端点可用性
- 每个代理端点:
- 项目1: /project1/bing-grounding/gpt4o_{1-12} - 项目2: /project2/bing-grounding/gpt4o_{1-12} - 项目3: /project3/bing-grounding/gpt4o_{1-12}
每月费用: 约6000美元(3个环境×每个环境2K美元)
何时使用:
- 需要高级路由逻辑(租户隔离、工作负载优先级)
- 希望对流量分布进行精细控制
- LLM套件已经具有负载平衡功能
- 每个项目的成本跟踪需求
______________________________________________________________________
策略4:混合动力-PTU+多项目
graph TB
subgraph External["External Clients"]
Client[LLM Suite / MCP Client]
end
subgraph APIM["Azure API Management - Weighted LB"]
Gateway[API Gateway
80% to PTU
20% to Standard]
end
subgraph PrimaryProject["Primary Project - PTU"]
CA_PTU[Container Apps
12 Agents]
Project_PTU[AI Project
GPT-4o PTU
100K TPM
Guaranteed]
end
subgraph FallbackProjects["Fallback Projects - Standard"]
CA_STD1[Container Apps
12 Agents]
Project_STD1[AI Project 1
GPT-4o: 10K TPM]
CA_STD2[Container Apps
12 Agents]
Project_STD2[AI Project 2
GPT-4o: 10K TPM]
end
Client -->|HTTPS| Gateway
Gateway -->|80% Primary| CA_PTU
Gateway -->|10% Spillover| CA_STD1
Gateway -->|10% Spillover| CA_STD2
CA_PTU --> Project_PTU
CA_STD1 --> Project_STD1
CA_STD2 --> Project_STD2
style Gateway fill:#0078d4,color:#fff
style CA_PTU fill:#4caf50,color:#fff
style Project_PTU fill:#ff6b6b,color:#fff
style CA_STD1 fill:#00bcf2,color:#000
style CA_STD2 fill:#00bcf2,color:#000实施:
- 部署主PTU项目:
# Modify infra/resources.bicep to use PTU
param openAiDeploymentType string = 'ProvisionedThroughput'
param openAiCapacity int = 100 # 100 PTUs
azd env new prod-primary
azd up- 部署后备标准项目:
azd env new prod-fallback-1
azd up
azd env new prod-fallback-2
azd up- 配置加权APIM路由:
特点:
- ✅ 保证容量 (PTU提供的10万TPM)
- ✅ 突发容量 (标准外增加20K TPM)
- ✅ 成本优化 -PTU为基准,按使用量付费
- ✅ 高可用性 -多个后备项目
- ⚠️ 复杂的配置 -加权路由+健康检查
- ⚠️ 基础成本较高 -PTU承诺
LLM套件集成:
- 无需更改 -单个APIM端点
- APIM自动处理加权路由
- 透明地切换到标准项目
每月费用: 约25000美元(PTU:21000美元+2个标准项目:4K美元)
何时使用:
- 需要有保证的基线容量(10万TPM)
- 预计PTU分配之外的流量峰值
- 希望通过突发功能实现成本可预测性
- 需要SLA的关键任务工作负载
______________________________________________________________________
比较矩阵
| 策略 | 最大TPM | HA | 成本/月 | LLM套件更改 | 复杂性 | 最适合 |
|---|---|---|---|---|---|---|
| 策略1:垂直(PTU) | 1M+ | 中等 | 5K-50K美元 | 无 | 低 | 快速扩展,可预测负载 |
| 策略2:横向(APIM LB) | 50000+ | 高 | 6000+美元 | 无 | 中等 | 成本效益,容错 |
| 策略3:横向(客户LB) | 50K+ | 高 | 6K+美元 | 配置+逻辑 | 高 | 高级路由,租户隔离 |
| 策略4:混合动力(PTU+多功能) | 12万+ | 非常高 | 2.5万+美元 | 无 | 高 | 关键任务,有保证的容量 |
______________________________________________________________________
按工作量推荐
**试点/开发(\ Gateway EUClient --> Gateway
Gateway -->|Geo-routing| CA_East Gateway -->|Load balance| CA_West Gateway -->|Geo-routing| CA_EU
CA_East --> Foundry_East CA_West --> Foundry_West CA_EU --> Foundry_EU
Foundry_East --> Bing_East Foundry_West --> Bing_West Foundry_EU --> Bing_EU
style Gateway fill:#0078d4,color:#fff style CA_East fill:#00bcf2,color:#000 style CA_West fill:#00bcf2,color:#000 style CA_EU fill:#00bcf2,color:#000
### 区域跟踪
每个响应都包含元数据,显示哪个区域处理了请求:
{ "content": "AI-generated response...", "citations": [...], "metadata": { "agent_route": "gpt4o_2", "model": "gpt-4o", "agent_id": "asst_abc123...", "region": "westus" ← Region identifier } }
这使得:
- **监控** -跟踪区域交通分布
- **调试** -识别特定地区的问题
- **合规** -审计数据驻留要求
- **分析** -衡量区域绩效
### 部署步骤
#### 1.部署其他区域
Create new environment for westus
azd env new westus azd env set AZURE_LOCATION westus
Deploy (creates full stack: Foundry, agents, Container App, etc.)
azd up
Get the Container App URL
azd env get-values | Select-String "CONTAINER_APP"
**输出:** 容器应用程序URL类似 `ca-abc123.westus.azurecontainerapps.io`
#### 2.配置APIM多区域后端
**选项A:随机负载平衡(最简单)**
编辑您的APIM API操作策略(`/bing-grounding` 或 `/bing-grounding-mcp`):
**选项B:地理路由(基于用户位置)**
**选项C:使用断路器进行健康检查(生产)**
();
// Check cached health status foreach (var backend in allBackends) { string cacheKey = "backend-health-" + backend; string healthStatus;
if (context.Cache.TryGetValue(cacheKey, out healthStatus)) { if (healthStatus == "healthy") healthyList.Add(backend); } else { healthyList.Add(backend); // Assume healthy if no data } }
return healthyList.Count > 0 ? healthyList : allBackends; }" />
)context.Variables["healthyBackends"]; var random = new Random(); return backends[random.Next(0, backends.Count)]; }" />
= 500)">
#### 3.测试多区域设置
运行测试套件并观察区域轮换:
python test_mcp.py
**预期产量:**
Test 1: Region: eastus Test 2: Region: westus Test 3: Region: eastus Test 4: Region: westus ...
### 各地区所需资源
每个区域部署都需要:
|资源|必填|备注|
|----------|----------|-------|
| **AI铸造中心+项目** | ✅ 是|每个地区的新实例|
| **Bing接地** | ✅ 是|必须与Foundry位于同一资源组中|
| **容器应用程序** | ✅ 是|这是端点APIM路由到|
| **容器应用程序环境** | ✅ 是|容器应用程序需要|
| **日志分析** | ✅ 是|用于容器应用程序日志记录|
| **存储帐户** |推荐|更适合区域隔离|
| **密钥库** |推荐|更好的可用性|
| **集装箱登记处** |可选|可以从主区域重复使用|
| **APIM** | ❌ 否|单个全球网关,跨区域重用|
### 成本考虑
**每个额外地区:**
- 人工智能铸造项目:~$0(按使用付费)
- GPT-4o部署(10K TPM):约800美元/月
- 容器应用程序:~50-100美元/月
- 集装箱环境:约50美元/月
- Bing停飞(免费版):0美元
- 存储+密钥库+日志:约50美元/月
**每个地区总计:** 约950-1000美元/月
**3区设置(美国东部、美国西部、西欧):**
- **总计:** 约3000美元/月
- **优点:** 30000 TPM总容量+地理分布+灾难恢复
### 最佳实践
1. **从两个地区开始** -主+故障转移
1. **使用健康检查** -实施断路器模式
1. **监控区域分布** -轨道 `metadata.region` 领域
1. **设置区域特定警报** -每个区域的Azure监视器
1. **测试故障转移** -定期验证自动故障转移是否正常工作
1. **缓存DNS** -考虑使用Azure Front Door进行高级地理路由
### 监控多区域
**Azure监视器查询(日志分析):**
ContainerAppConsoleLogs_CL | where TimeGenerated > ago(1h) | extend region = tostring(parse_json(Log_s).metadata.region) | summarize count() by region, bin(TimeGenerated, 5m) | render timechart
**APIM分析:**
在APIM中跟踪后端分发→ 分析→ 自定义尺寸
______________________________________________________________________
## 先决条件
### 促进地方发展
- **Python 3.11+** - [下载](https://www.python.org/downloads/)
- **Azure命令行界面** - [安装指南](https://learn.microsoft.com/cli/azure/install-azure-cli)
- **Docker 桌面版** (可选,适用于Docker Compose)- [下载](https://www.docker.com/products/docker-desktop)
- **Azure订阅** 可以访问:
- Azure AI 铸造厂
- Azure容器应用
- Azure API管理(可选,用于生产)
### 用于Azure部署
- **Azure开发者命令行界面(azd)** - [安装指南](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd)
- **码头工人** (用于构建集装箱图像)- [下载](https://www.docker.com/products/docker-desktop)
- **Azure命令行界面** - [安装指南](https://learn.microsoft.com/cli/azure/install-azure-cli)
### 需要Azure权限
- **订阅贡献者** 或 **所有者** 角色(创建资源组和资源)
- **Azure人工智能开发人员** 或 **认知服务贡献者** (创建AI Foundry项目)
______________________________________________________________________
## 入门指南
### 本地开发
1. **创建虚拟环境**
_env_create.bat
1. **激活虚拟环境**
_env_activate.bat
1. **安装依赖项**
_install.bat
1. **配置环境变量**
- 复制 `env.sample` 到 `.env`
- 填写您的Azure AI代理凭据:AZURE_AI_PROJECT_ENDPOINT="https://your-project.services.ai.azure.com/api/projects/yourProject" AZURE_AI_AGENT_ID="asst_xxxxxxxxxxxxx"
1. **启动服务器**
_run_server.bat
API将于 `http://localhost:8989`
### Docker开发
1. **从Docker Compose开始**
_up.bat
1. **停止Docker编写**
_down.bat
## API终点
### GET/健康
验证服务是否正在运行的健康检查终结点。
**例子:**
curl http://localhost:8989/health
**答复:**
{ "status": "ok", "service": "bing-grounding-api", "region": "eastus", "agents_loaded": 5 }
### POST/bing接地
Azure AI Agent包装器端点,支持Bing基础和引用。
**参数:**
- `query` (string,必填)-要处理的用户查询
**例子:**
curl -X POST "http://localhost:8989/bing-grounding?query=What+happened+in+finance+today?"
**成功响应:**
{ "content": "Today in finance, the U.S. stock market saw a sharp decline, with the Dow Jones Industrial Average plunging almost 800 points (down 1.6%), and both the Nasdaq and S&P 500 also posting significant losses...", "citations": [ { "id": 1, "type": "url", "url": "https://www.marketwatch.com/...", "title": "Stock Market News Today" }, { "id": 2, "type": "url", "url": "https://www.cnbc.com/...", "title": "Federal Reserve Commentary" } ], "metadata": { "agent_route": "gpt4o_1", "model": "gpt-4o", "agent_id": "asst_abc123...", "region": "eastus" } }
**错误响应:**
{ "error": "processing_error", "message": "Error details...", "metadata": { "agent_route": "gpt4o_1", "model": "gpt-4o", "agent_id": "asst_abc123...", "region": "eastus" } }
**特征:**
- ✅ 使用Bing搜索的固定响应
- ✅ 自动引文提取和格式化
- ✅ 干净的内容(删除内联引用标记)
- ✅ 结构化JSON响应
- ✅ 元数据中的区域跟踪
### 响应元数据(调试信息)
每个API响应都包含 `metadata` 带有调试信息的对象:
|字段|类型|描述|示例|目的|
|-------|------|-------------|---------|---------|
| `region` |string |为请求提供服务的Azure区域| `"eastus"`, `"westus"` |跟踪多区域负载平衡;确定区域问题|
| `model` |string |用于生成的AI模型| `"gpt-4o"`, `"gpt-4o-mini"` |验证模型部署是否正确;比较模型性能|
| `agent_route` |string |代理池标识符| `"gpt4o_1"`, `"gpt4o_5"` |负载均衡验证;识别特定代理的问题|
| `agent_id` |string | Azure AI代理实例ID| `"asst_ElHsNtK1PSFxwha7..."` |跟踪特定代理人的行为;排除代理错误|
**为什么元数据对调试很重要:**
1. **多区域部署** -了解哪个区域处理了诊断延迟或区域中断的请求
1. **负载平衡验证** -确认APIM正在跨代理池分发(`gpt4o_1` 通过 `gpt4o_5`)
1. **性能分析** -比较不同地区、模型或代理的响应时间/质量
1. **错误排除** -确定错误是否隔离到特定的代理、区域或模型
1. **合规与审计** -根据监管要求跟踪数据驻留和模型使用情况
**元数据成功响应示例:**
{ "content": "Azure AI Foundry is a comprehensive platform for building, deploying, and managing AI applications...", "citations": [ { "id": 1, "type": "url", "url": "https://azure.microsoft.com/products/ai-studio", "title": "Azure AI Foundry Documentation" } ], "metadata": { "agent_route": "gpt4o_3", // ← Agent pool #3 (load balanced) "model": "gpt-4o", // ← Using GPT-4o model "agent_id": "asst_ElHsNtK1PSFxwha7tLWIFM7T", // ← Specific agent instance "region": "eastus" // ← Request served from East US } }
**元数据错误响应示例:**
{ "error": "rate_limit_exceeded", "message": "Model deployment TPM limit exceeded. Please retry.", "metadata": { "agent_route": "gpt4o_2", // ← Identifies which agent hit rate limit "model": "gpt-4o", "agent_id": "asst_abc123xyz", "region": "westus" // ← Regional capacity issue } }
**调试用例示例:**
|问题|检查内容|解决方案|
|-------|---------------|----------|
|某些请求的响应缓慢| `region` 字段|可能表示一个区域过载;增加容量或调整APIM路由|
|间歇性429错误| `agent_route` + `agent_id` |特定代理的TPM配额可能较低;增加配额或重新分配负载|
|质量变化| `model` + `agent_id` |比较不同代理人的反应;可能需要及时调整|
|区域合规违规| `region` 字段|审核日志显示在错误区域处理的数据;更新地理路由策略|
|所有请求都发送给一个代理| `agent_route` 分布|APIM负载平衡中断;检查后端池配置|
**如何添加元数据(实现):**
元数据填充在 [`app/main.py`](app/main.py):
Environment variable set by Bicep deployment
AZURE_REGION = os.getenv("AZURE_REGION", "unknown")
On successful response (line ~133)
result["metadata"] = { "agent_route": agent_route, # From URL path (gpt4o_1, gpt4o_2, etc.) "model": model, # From agent configuration "agent_id": AGENTS[agent_route]["agent_id"], # From agent pool "region": AZURE_REGION # From container environment }
On error response (line ~147)
"metadata": { "agent_route": agent_route, "model": model, "agent_id": AGENTS.get(agent_route, {}).get("agent_id", "unknown"), "region": AZURE_REGION }
这 `AZURE_REGION` 环境变量在部署过程中通过二头肌自动设置([`infra/resources.bicep`](infra/resources.bicep) 第258行):
{ name: 'AZURE_REGION' value: location // Resolves to deployment region (eastus, westus, etc.) }
______________________________________________________________________
## 测试API
### 测试API直接端点
**先决条件:**
- 已部署服务(本地或Azure)
- 来自部署的终结点URL或 `http://localhost:8989` 本地
**基本健康检查:**
Local
curl http://localhost:8989/health
Azure (Container App)
curl https://ca-vw5lt6yc7noze.eastus.azurecontainerapps.io/health
**预期响应:**
{ "status": "ok", "service": "bing-grounding-api", "region": "eastus", "agents_loaded": 5 }
**测试查询:**
Local
curl -X POST "http://localhost:8989/bing-grounding/gpt4o_1?query=What+is+Azure+AI+Foundry?"
Azure (Container App)
curl -X POST "https://ca-vw5lt6yc7noze.eastus.azurecontainerapps.io/bing-grounding/gpt4o_1?query=What+is+Azure+AI+Foundry?"
**预期响应:**
{ "content": "Azure AI Foundry is Microsoft's unified platform...", "citations": [ { "id": 1, "type": "url", "url": "https://azure.microsoft.com/products/ai-studio", "title": "Azure AI Foundry Overview" } ], "metadata": { "agent_route": "gpt4o_1", "model": "gpt-4o", "agent_id": "asst_ElHsNtK1PSFxwha7tLWIFM7T", "region": "eastus" } }
______________________________________________________________________
### 测试MCP端点(模型上下文协议)
MCP端点通过Azure API管理为人工智能模型消费提供标准化接口。
#### 先决条件
1. **APIM部署** -API管理必须部署(包含在 `azd up`)
1. **订阅密钥** -APIM身份验证所需
**获取您的订阅密钥:**
Option 1: Azure Portal
Navigate to: APIM → Subscriptions → "Built-in all-access subscription" → Show keys
Option 2: Azure CLI
az apim subscription show \ --resource-group rg-bing-grounding-mcp-dev \ --service-name apim-xxxxxx \ --sid master \ --query primaryKey -o tsv
#### 配置环境变量
将这些添加到您的 `.env` 文件:
MCP Server URL (from APIM)
APIM_MCP_SERVER_URL=https://apim-vw5lt6yc7noze.azure-api.net/bing-grounding-mcp/mcp
Subscription Key (from APIM portal or CLI)
APIM_SUBSCRIPTION_KEY=70f2c804e2ee4f749cea4b8ab3246e7e
#### 运行MCP测试
**使用测试脚本:**
Activate virtual environment
_env_activate.bat
Run tests
python test_mcp.py
**预期产量:**
=== Testing MCP Endpoint === MCP Server URL: https://apim-vw5lt6yc7noze.azure-api.net/bing-grounding-mcp/mcp
Test 1: What are the latest developments in AI? RESULT: OK (10.6s) Region: eastus ← Azure region that processed request Model: gpt-4o ← AI model used for generation Agent Route: gpt4o_2 ← Agent pool identifier (load balanced) Agent ID: asst_ElHsNtK1PSFxwha7tLWIFM7T ← Specific agent instance ID Citations: 3 ← Number of Bing grounding citations [1] AI News December 2025: In-Depth and Concise [2] Recent Developments in Generative AI Research [3] OpenAI Announces GPT-4.5
Response: During December 2025, several notable advancements have been made in artificial intelligence...
Test 2: What happened in the stock market today? RESULT: OK (8.2s) Region: westus ← Different region (multi-region load balancing) Model: gpt-4o Agent Route: gpt4o_3 ← Different agent (load balanced across 5 agents) Agent ID: asst_xyz789... Citations: 4 [1] Market Watch - December 17, 2025 [2] CNBC Stock Market Update [3] Bloomberg Markets Summary [4] S&P 500 Daily Close
Response: Today's stock market showed mixed performance, with the S&P 500 closing up 0.3%...
Test 3: Explain quantum computing RESULT: OK (12.1s) Region: eastus ← Back to eastus (round-robin balancing) Model: gpt-4o Agent Route: gpt4o_1 ← Cycling through agent pool Agent ID: asst_def456... Citations: 5 [1] Quantum Computing Basics - Nature [2] IBM Quantum - Overview [3] Google Quantum AI Research [4] Quantum Algorithms Explained [5] Introduction to Qubits
Response: Quantum computing is a revolutionary approach to computation that leverages quantum mechanics...
=========================== Tests completed: 5 Success: 5 (100%) Failed: 0 (0%) Average response time: 9.4s ===========================
**在测试输出中查找什么:**
|字段|它告诉你什么|很好✅ | 坏❌ |
|-------|-------------------|---------|--------|
| **区域** |地理分布|跨地区轮换(东、西)|始终是同一地区;“未知”|
| **代理路线** |跨代理的负载平衡|通过gpt4o_1循环到gpt4i_5 |始终使用相同的代理路由|
| **响应时间** |性能一致性|5-15秒典型|>30秒;高方差|
| **成功率** |总体可靠性|90%+成功|\ \
--role "Cognitive Services User" \
--scope "/subscriptions//resourceGroups//providers/Microsoft.CognitiveServices/accounts/"- 更新你的
.env文件:
AZURE_AI_PROJECT_ENDPOINT=https://your-region.services.ai.azure.com/api/projects/your-project
AZURE_AI_AGENT_ID=asst_xxxxxxxxxxxxx
AZURE_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
AZURE_CLIENT_SECRET=your-secret-here
AZURE_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx用于生产(管理身份)
部署到Azure容器应用程序时,请改用托管身份:
- 启用托管身份 在您的容器应用程序上:
az containerapp identity assign \
--name bing-grounding-api \
--resource-group your-rg \
--system-assigned- 授予托管身份访问权限 您的AI项目:
# Get the principal ID from the output above or:
PRINCIPAL_ID=$(az containerapp identity show \
--name bing-grounding-api \
--resource-group your-rg \
--query principalId -o tsv)
# Grant access
az role assignment create \
--assignee $PRINCIPAL_ID \
--role "Cognitive Services User" \
--scope "/subscriptions//resourceGroups//providers/Microsoft.CognitiveServices/accounts/"- 仅使用所需变量进行部署 (无客户机密):
az containerapp create \
--name bing-grounding-api \
--resource-group your-rg \
--environment your-env \
--image your-registry.azurecr.io/bing-grounding-api:latest \
--target-port 8989 \
--ingress external \
--system-assigned \
--env-vars \
AZURE_AI_PROJECT_ENDPOINT="your-endpoint" \
AZURE_AI_AGENT_ID="your-agent-id"重要:不设置 AZURE_CLIENT_ID, AZURE_CLIENT_SECRET,或 AZURE_TENANT_ID 在生产中。这 DefaultAzureCredential 将自动使用托管身份。
项目结构
ai-bing-grounding-mcp/
├── agents/ # AI Agent implementations
│ ├── __init__.py
│ ├── base_agent.py # Abstract base class
│ └── bing_grounding.py # Bing grounding agent
├── ai/ # (Legacy - not used)
│ ├── __init__.py
│ └── azure_openai_client.py
├── app/ # FastAPI application
│ ├── __init__.py
│ └── main.py # API endpoints
├── apim-policy.xml # Main APIM policy (load balancing + circuit breaker)
├── apim-policy-with-healthcheck.xml # Enhanced APIM policy with active health checks
├── apim-healthcheck-monitor.xml # Optional active health monitoring policy
├── docker-compose.yaml # Local Docker development
├── dockerfile # Container image definition
├── env.sample # Environment variable template
├── main.py # Application entry point
├── requirements.txt # Python dependencies
├── _env_activate.bat # Activate virtual environment
├── _env_create.bat # Create virtual environment
├── _install.bat # Install dependencies
├── _run_server.bat # Run FastAPI server
├── _up.bat # Start Docker Compose
├── _down.bat # Stop Docker Compose
└── README.md # This file部署到Azure
选项1:使用Azure Developer CLI自动部署(⭐ 推荐)
Azure开发者命令行界面(azd)自动化了从创建基础设施到部署应用程序的整个部署过程。 这是推荐的方法 用于开发和生产部署。
自动部署的内容:
- 🏗️ Azure容器应用环境+3个容器应用实例
- 🤖 Azure人工智能铸造中心和项目
- 🤖 12个基于Bing的GPT-4o AI代理(通过编程创建!)
- 🔐 Azure容器注册表
- 🔐 具有受管理身份的密钥库
- 📊 日志分析和应用洞察
- 🌐 Azure API管理(带负载平衡和断路器)
- 🔒 所有资源的RBAC角色分配
总部署时间:~8-15分钟 ⏱️
______________________________________________________________________
先决条件
在开始之前,请确保您已经:
必修的:
可选(用于当地发展):
- Python 3.11+- 下载
快速安装命令:
# Windows (PowerShell)
powershell -ex AllSigned -c "Invoke-RestMethod 'https://aka.ms/install-azd.ps1' | Invoke-Expression"
# macOS/Linux
curl -fsSL https://aka.ms/install-azd.sh | bash______________________________________________________________________
第一步:登录Azure
azd auth login这将打开一个浏览器进行身份验证。一旦通过身份验证,您就可以部署了。
______________________________________________________________________
步骤2:部署所有内容(一个命令)
最简单的方法是使用 azd up,它一步创建环境、配置基础设施并部署应用程序:
azd up系统将提示您:
- 环境名称例如。,
dev,staging,prod
- 创建资源组: rg-bing-grounding-mcp-{env-name}
- Azure订阅:从您的订阅中选择
- Azure位置例如。,
eastus2,westus2 - 资源组确认:如果已存在,请确认继续
期间会发生什么 azd up:
- 预浸挂钩 (约30秒)
- ✅ 检查资源组状态 - ✅ 注册Microsoft。Bing资源提供者
- 基础设施供应 (约5-10分钟)
- 🏗️ 创建容器注册表 - 🏗️ 创建容器应用程序环境 - 🏗️ 创建AI铸造中心和项目 - 🏗️ 部署GPT-4o模型 - 🏗️ 创建密钥库、存储、日志分析 - 🏗️ 创建API管理 - 🏗️ 配置托管身份和RBAC
- 供应后挂钩 (约2-3分钟)
- 🤖 使用Bing基础创建12个GPT-4o AI代理 - 📝 将代理ID保存到环境
- 应用程序部署 (约3-5分钟)
- 🐳 构建Docker镜像 - 📤 推送到Azure容器注册表 - 🚀 部署到所有3个容器应用程序实例
- 部署后挂钩 (约1分钟)
- 🔄 更新其他容器实例
完成后,您将看到:
SUCCESS: Your application was provisioned and deployed to Azure in X minutes.
You can view the application at https://ca-xxxxxx.eastus2.azurecontainerapps.io就是这样!您的API有12个人工智能代理,随时准备为请求提供服务。
______________________________________________________________________
步骤2(备选方案):单独提供和部署
如果您更喜欢控制,可以将步骤分开:
A.创造环境:
azd env new 示例:
azd env new dev→ 创建rg-bing-grounding-mcp-devazd env new prod→ 创建rg-bing-grounding-mcp-prod
B.提供基础设施:
azd provision这将创建所有Azure资源,并运行后视觉挂钩以创建AI代理。
C.部署应用程序:
azd deploy这将构建Docker容器并将其部署到所有实例。
______________________________________________________________________
步骤3:测试部署
获取您的端点:
azd env get-values | grep AZURE_CONTAINER_APP_ENDPOINT
# or
azd env get-values | findstr AZURE_CONTAINER_APP_ENDPOINT # Windows测试API:
# Health check
curl https://ca-xxxxxx.eastus2.azurecontainerapps.io/health
# List agents
curl https://ca-xxxxxx.eastus2.azurecontainerapps.io/agents
# Query with Bing grounding
curl -X POST "https://ca-xxxxxx.eastus2.azurecontainerapps.io/bing-grounding/gpt4o_1?query=What+is+Azure+AI+Foundry?"______________________________________________________________________
高级配置
预配置环境(可选)
对于CI/CD管道或脚本部署,您可以预先配置值以避免交互式提示:
# Create environment
azd env new
# Set subscription (find with: az account list -o table)
azd env set AZURE_SUBSCRIPTION_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# Set location
azd env set AZURE_LOCATION "eastus2"
# Now provision and deploy without prompts
azd up何时进行预配置:
- ✅ CI/CD管道(GitHub操作、Azure DevOps)
- ✅ 自动化/脚本化部署
- ✅ 执行团队标准
- ✅ 多环境部署(开发/测试/生产)
查看环境配置
# Show all environment variables and outputs
azd env get-values
# Show deployment status and endpoints
azd show______________________________________________________________________
常见工作流
更新应用程序代码
当你修改Python代码时:
azd deploy这将重建Docker镜像,并在零停机时间(约3-5分钟)内更新所有容器应用程序实例。
更新基础架构
在中修改二头肌模板时 infra/:
azd provision这将应用基础设施更改,而无需重新部署应用程序(约2-5分钟)。
查看日志
# Get resource group from environment
RG=$(azd env get-values | grep AZURE_RESOURCE_GROUP | cut -d'=' -f2 | tr -d '"')
# Get Container App name
CA_NAME=$(azd env get-values | grep AZURE_CONTAINER_APP_NAME | cut -d'=' -f2 | tr -d '"')
# Stream logs
az containerapp logs show --name $CA_NAME --resource-group $RG --follow多种环境(开发/暂存/生产)
# Create and deploy dev environment
azd env new dev
azd env set AZURE_LOCATION "eastus2"
azd up
# Create and deploy prod environment
azd env new prod
azd env set AZURE_LOCATION "eastus"
azd up
# Switch between environments
azd env select dev
azd env select prod
# List all environments
azd env list每个环境都会得到:
- 单独的资源组:
rg-bing-grounding-mcp-{env} - 隔离的Azure资源
- 本地配置
.azure/{env}/
拆除资源
# Delete all Azure resources (with confirmation)
azd down
# Delete without prompts
azd down --force --purge⚠️ 警告:这将删除整个资源组和所有资源。
______________________________________________________________________
什么是自动创建的
当你奔跑时 azd up,提供以下资源:
| 资源 | 目的 | 详细信息 |
|---|---|---|
| 资源组 | 逻辑容器 | rg-bing-grounding-mcp-{env} |
| 集装箱登记处 | Docker镜像 | 应用镜像的私有注册表 |
| 容器应用程序(×3) | 应用程序托管 | 3个负载平衡实例 |
| AI铸造中心 | 人工智能基础设施 | 人工智能项目中心 |
| AI铸造项目 | AI代理管理 | 包含GPT-4o部署 |
| 12个AI代理 | 必应基础代理 | 通过API以编程方式创建 |
| API管理 | API网关 | 负载平衡+断路器 |
| 密钥库 | 机密管理 | 存储敏感配置 |
| 存储帐户 | 数据存储 | 用于AI Hub和日志 |
| 日志分析 | 监控 | 集中记录 |
| 应用洞察 | APM | 性能监控 |
| 管理身份 | 身份验证 | 安全的服务到服务身份验证 |
总成本估算:根据使用情况和SKU,每月约200-400美元。
______________________________________________________________________
自动挂钩解释
该解决方案使用 azd 钩子用于自动化设置任务:
预浸挂钩 (基础设施之前):
- 检查资源组 -提示RG是否已存在
- 注册供应商 -登记簿
Microsoft.Bing提供者
供应后挂钩 (基础设施之后):
- 创建AI代理 -以Bing为基础,通过编程创建12个GPT-4o代理
- 保存代理ID -将ID存储为环境变量
部署后挂钩 (部署后):
- 更新容器实例 -使用最新映像更新其他实例
这些钩子在 azure.yaml 并自动运行- 无需人工干预.
______________________________________________________________________
部署故障排除
问题: azd provision 订阅失败
- 修复:明确设置订阅:
azd env set AZURE_SUBSCRIPTION_ID "your-sub-id" - 修复:确保您在订阅中具有参与者/所有者角色
问题:容器部署失败,显示“找不到映像”
- 修复:确保Docker在本地运行
- 修复:检查ACR凭据:
az acr login --name
问题:未创建AI代理
- 修复:检查日志:
cat .azure/{env}/.env | grep AZURE_AI_AGENT - 修复:手动运行:
python scripts/postprovision_create_agents.py
问题:访问AI项目时出现身份验证错误
- 修复:验证托管身份是否具有“认知服务用户”角色
- 修复:检查Azure门户中的RBAC分配
______________________________________________________________________
最佳实践
✅ 使用 azd up 用于首次部署和组合基础架构+代码更改\ ✅ 使用 azd deploy 仅用于代码更改(更快)\ ✅ 使用单独的环境 用于dev/ststage/prod隔离\ ✅ 永不承诺 .azure/ 文件夹 -它包含特定于环境的配置\ ✅ 审查产出 每次部署后 azd env get-values\ ✅ 测试在dev 部署到生产环境之前\ ✅ 使用托管身份 (默认)而不是服务主体\ ✅ 监控成本 使用Azure成本管理
______________________________________________________________________
📚 了解更多:
______________________________________________________________________
选项2:使用Azure CLI手动部署
如果您喜欢手动控制或无法使用 azd:
第一步:创建基础设施
- 创建资源组:
az group create --name rg-bing-grounding --location eastus- 创建Azure容器注册表:
az acr create \
--resource-group rg-bing-grounding \
--name acrbing123 \
--sku Basic \
--admin-enabled true- 创建AI铸造中心和项目 (通过Azure门户):
- 首选https://ai.azure.com - 创建新中心 - 在Hub中创建新项目 - 注意项目端点
- 创建容器应用程序环境:
az containerapp env create \
--name cae-bing-grounding \
--resource-group rg-bing-grounding \
--location eastus步骤2:构建并推送容器映像
- 登录ACR:
az acr login --name acrbing123- 构建和推送图像:
docker build -t acrbing123.azurecr.io/bing-grounding-api:latest .
docker push acrbing123.azurecr.io/bing-grounding-api:latest步骤3:部署容器应用程序(多个实例)
# Get ACR credentials
ACR_USERNAME=$(az acr credential show --name acrbing123 --query username -o tsv)
ACR_PASSWORD=$(az acr credential show --name acrbing123 --query passwords[0].value -o tsv)
# Deploy instance 1
az containerapp create \
--name bing-grounding-api-0 \
--resource-group rg-bing-grounding \
--environment cae-bing-grounding \
--image acrbing123.azurecr.io/bing-grounding-api:latest \
--target-port 8989 \
--ingress external \
--registry-server acrbing123.azurecr.io \
--registry-username $ACR_USERNAME \
--registry-password $ACR_PASSWORD \
--system-assigned \
--env-vars \
AZURE_AI_PROJECT_ENDPOINT="https://eastus.services.ai.azure.com/api/projects/yourProject" \
AZURE_AI_AGENT_ID="asst_xxxxxxxxxxxxx"
# Repeat for instances 1 and 2
az containerapp create --name bing-grounding-api-1 ... (same parameters)
az containerapp create --name bing-grounding-api-2 ... (same parameters)步骤4:授予托管身份访问权限
# Get managed identity principal IDs
PRINCIPAL_ID_0=$(az containerapp identity show \
--name bing-grounding-api-0 \
--resource-group rg-bing-grounding \
--query principalId -o tsv)
# Grant access to AI Project (repeat for each instance)
az role assignment create \
--assignee $PRINCIPAL_ID_0 \
--role "Cognitive Services User" \
--scope "/subscriptions//resourceGroups/rg-bing-grounding/providers/Microsoft.CognitiveServices/accounts/"步骤5:更新容器应用程序(用于代码更改)
# Build and push new image
docker build -t acrbing123.azurecr.io/bing-grounding-api:v2 .
docker push acrbing123.azurecr.io/bing-grounding-api:v2
# Update container apps
az containerapp update \
--name bing-grounding-api-0 \
--resource-group rg-bing-grounding \
--image acrbing123.azurecr.io/bing-grounding-api:v2
# Repeat for other instances______________________________________________________________________
使用Docker Compose进行本地开发
对于没有Azure资源的本地测试:
# Start services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose down备注:您仍然需要有效的Azure AI项目凭据 .env 文件。
______________________________________________________________________
Azure API管理设置
断路器负载平衡
该服务包括用于具有多个后端实例的生产部署的APIM策略。
架构特征
┌──────────────────────────────────────────┐
│ [AZURE API MANAGEMENT] │
│ │
│ ┌────────────────────────────────────┐ │
│ │ Load Balancer + Circuit Breaker │ │
│ │ • Session Affinity (Cookies) │ │
│ │ • Health-Based Routing │ │
│ │ • Auto Failover & Recovery │ │
│ └─────────────────┬──────────────────┘ │
└────────────────────┼────────────────────┘
│
┌───────────┼───────────┐
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ... (N instances)
│ ✅ HEALTHY │ │ ❌ UNHEALTHY│
│ Container │ │ Container │
│ App #1 │ │ App #2 │
│ [ACTIVE] │ │ [REMOVED] │
└─────────────┘ └─────────────┘特性
- 会话亲和性(粘性会话) -客户端通过Cookie坚持使用相同的后端
- 断路器 -不健康的后端已自动从池中删除
- 自动恢复 -健康恢复后,后端重新加入
- 健康感知路由 -仅通往健康实例的路径
APIM策略文件
包括三个策略文件:
| 文件 | 描述 | 用例 |
|---|---|---|
apim-policy.xml | 具有会话关联性和断路器的主要负载平衡策略 | 推荐 -具有多个后端的生产部署 |
apim-policy-with-healthcheck.xml | 通过主动健康监测增强策略 | 需要主动健康检查的高可用性场景 |
apim-healthcheck-monitor.xml | 独立健康检查监测器 | 单独的监测管道 |
设置步骤
- 更新后端URL
在 apim-policy.xml,将占位符URL替换为容器应用程序URL:
var backends = new System.Collections.Generic.Dictionary {
{ "0", "https://bing-grounding-api-1.azurecontainerapps.io" },
{ "1", "https://bing-grounding-api-2.azurecontainerapps.io" },
{ "2", "https://bing-grounding-api-3.azurecontainerapps.io" },
{ "3", "https://bing-grounding-api-4.azurecontainerapps.io" },
{ "4", "https://bing-grounding-api-5.azurecontainerapps.io" }
};- 在Azure门户中应用策略
- 导航到您的APIM服务 - 转到您的API→ 设计表 - 点击“所有操作”(或特定操作) - 在“入站处理”中,单击代码编辑器(`) - 从粘贴策略XML apim-policy.xml` - 点击保存
- 启用内部缓存 (断路器要求)
- 导航到APIM→ 缓存 - 启用内置缓存
断路器行为
❌ 不健康-标记背部不健康
后端已标记 \[不健康\] (从池中删除30秒):
- 退货
500,502,503,504(服务器错误) - 退货
429(超出费率限制) - 退货
401(身份验证失败) - 连接超时或失败
✅ 健康-自动恢复
后端已标记 \[健康\] (重新加入池)当:
- 退货
200 OK - 健康状态缓存过期(30秒后)
用于监视的响应标头
APIM策略添加了用于监视的标头:
| 标题 | 描述 | 示例 |
|---|---|---|
X-APIM-Correlation-Id | 用于跟踪的唯一请求ID | a1b2c3d4-... |
X-Backend-Instance | 处理请求的后端 | 0, 1, 2, 3, 4 |
X-Served-By-Instance | 为响应提供服务的后端 | 0, 1, 2, 3, 4 |
X-Error-Backend-Instance | 导致错误的后端(在错误时) | 2 |
饼干:
APIM-Backend-Instance-会话关联cookie(24小时TTL)
测试断路器
- 测试会话相关性
# First request - receives backend assignment
curl -i https://your-apim.azure-api.net/bing-grounding
# Check Set-Cookie header for: APIM-Backend-Instance=X
# Subsequent requests with cookie go to same backend
curl -i https://your-apim.azure-api.net/health \
-H "Cookie: APIM-Backend-Instance=0"- 测试故障转移
# Stop one Container App instance
# Requests automatically route to healthy instances
for i in {1..10}; do
curl -s https://your-apim.azure-api.net/health | jq '.status'
done- 测试恢复
# Restart the instance
# Wait 30 seconds for cache expiration
# It automatically rejoins on first 200 response生产检查表
- \[\]APIM中启用了内部缓存
- \[\]部署并运行多个容器应用程序
- \[\]健康端点返回200 OK
- \[\]APIM策略中更新了后端URL
- \[\]已应用和测试的政策
- \[\]使用Cookie测试会话相关性
- \[\]断路器经过模拟故障测试
- \[\]已配置监控/警报(应用程序洞察)
- \[\]安全性:已配置APIM订阅密钥
______________________________________________________________________
代理架构
包装器使用抽象基类(ABC)模式进行扩展:
agents/
├── base_agent.py # Abstract base class for all agents
└── bing_grounding.py # Bing grounding implementationBaseAgent(ABC)
class BaseAgent(ABC):
"""Abstract base class for all agents"""
def __init__(self, endpoint: str = None, agent_id: str = None):
self.endpoint = endpoint
self.agent_id = agent_id
@abstractmethod
def chat(self, message: str) -> str:
"""Process a message and return response"""
passBingGrounding代理
具体实施:
- 连接到Azure AI代理服务
- 创建对话线程
- 从基于Bing的回复中提取引文并格式化引文
- 返回包含内容和引用的结构化JSON
- 处理后自动清理线程
使用新代理进行扩展
要添加新的代理类型,请执行以下操作:
- 创建一个新的代理类,该类继承自
BaseAgent - 实施
chat()方法 - 将配置添加到
.env - 在中添加新端点
app/main.py
例子:
class CustomAgent(BaseAgent):
def __init__(self):
endpoint = os.getenv("CUSTOM_AGENT_ENDPOINT")
agent_id = os.getenv("CUSTOM_AGENT_ID")
super().__init__(endpoint=endpoint, agent_id=agent_id)
def chat(self, message: str) -> str:
# Your custom implementation
pass故障排除
问题:“AZURE_AI_PROJECT_ENDPOINT未设置”错误
- 修复:复制
env.sample到.env并填写您的凭据
问题:Azure AI代理的身份验证失败
- 修复:确保您已通过Azure CLI的身份验证:
az login - 修复:验证DefaultAzureCredentials是否有权访问AI项目
问题:没有引用回应
- 修复:确保您的Azure AI代理启用了Bing基础
- 修复:检查Azure AI Studio中是否正确配置了代理
问题:线程清理失败
- 修复:这些已记录,但不影响响应
- 修复:检查Azure AI代理服务限制和配额
生产安全最佳实践
为了简单起见,默认部署使用公共端点。对于生产工作负载,您应该通过专用网络和其他控制来增强安全性。
当前安全配置
✅ 托管身份 -容器应用程序向AI项目进行身份验证,没有秘密\ ✅ 基于角色的访问控制 -对所有资源进行基于角色的访问控制\ ✅ 仅限HTTPS -所有在传输过程中加密的流量\ ✅ ACR身份验证 -安全的容器注册表访问\ ✅ 密钥库RBAC -基于角色的密钥库授权
⚠️ 公共端点 -可从互联网访问的资源(适用于开发/测试)
推荐的生产增强功能
1.具有虚拟网络集成的专用网络
添加ExpressRoute集成以将资源与公共互联网隔离:
// Add to resources.bicep
// Virtual Network
resource vnet 'Microsoft.Network/virtualNetworks@2023-05-01' = {
name: 'vnet-${uniqueString(resourceGroup().id)}'
location: location
tags: tags
properties: {
addressSpace: {
addressPrefixes: ['10.0.0.0/16']
}
subnets: [
{
name: 'subnet-containerapp'
properties: {
addressPrefix: '10.0.0.0/23'
delegations: [
{
name: 'Microsoft.App/environments'
properties: {
serviceName: 'Microsoft.App/environments'
}
}
]
}
}
{
name: 'subnet-privateendpoints'
properties: {
addressPrefix: '10.0.2.0/24'
privateEndpointNetworkPolicies: 'Disabled'
}
}
]
}
}
// Update Container App Environment with VNet
resource containerAppEnv 'Microsoft.App/managedEnvironments@2023-05-01' = {
name: containerAppEnvName
location: location
tags: tags
properties: {
vnetConfiguration: {
infrastructureSubnetId: vnet.properties.subnets[0].id
internal: true // Make it internal for production
}
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: logAnalytics.properties.customerId
sharedKey: logAnalytics.listKeys().primarySharedKey
}
}
}
}2.Azure服务的专用端点
使用专用端点保护后端服务:
// Private DNS Zones (add to resources.bicep)
resource privateDnsZoneStorage 'Microsoft.Network/privateDnsZones@2020-06-01' = {
name: 'privatelink.blob.core.windows.net'
location: 'global'
tags: tags
}
resource privateDnsZoneKeyVault 'Microsoft.Network/privateDnsZones@2020-06-01' = {
name: 'privatelink.vaultcore.azure.net'
location: 'global'
tags: tags
}
resource privateDnsZoneACR 'Microsoft.Network/privateDnsZones@2020-06-01' = {
name: 'privatelink.azurecr.io'
location: 'global'
tags: tags
}
// Link DNS Zones to VNet
resource privateDnsZoneLinkStorage 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = {
parent: privateDnsZoneStorage
name: 'link-storage'
location: 'global'
properties: {
registrationEnabled: false
virtualNetwork: {
id: vnet.id
}
}
}
// Private Endpoint for Storage Account
resource privateEndpointStorage 'Microsoft.Network/privateEndpoints@2023-05-01' = {
name: 'pe-storage-${uniqueString(resourceGroup().id)}'
location: location
tags: tags
properties: {
subnet: {
id: vnet.properties.subnets[1].id // Private endpoints subnet
}
privateLinkServiceConnections: [
{
name: 'storage-connection'
properties: {
privateLinkServiceId: storage.id
groupIds: ['blob']
}
}
]
}
}
// Private DNS Zone Group for Storage
resource privateDnsZoneGroupStorage 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2023-05-01' = {
parent: privateEndpointStorage
name: 'default'
properties: {
privateDnsZoneConfigs: [
{
name: 'config-storage'
properties: {
privateDnsZoneId: privateDnsZoneStorage.id
}
}
]
}
}
// Update Storage Account to disable public access
resource storage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: 'st${uniqueString(resourceGroup().id)}'
location: location
tags: tags
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
accessTier: 'Hot'
supportsHttpsTrafficOnly: true
minimumTlsVersion: 'TLS1_2'
publicNetworkAccess: 'Disabled' // Changed from default
networkAcls: {
defaultAction: 'Deny'
bypass: 'AzureServices'
}
}
}
// Repeat similar patterns for:
// - Key Vault private endpoint
// - Container Registry private endpoint
// - AI Hub/Project (if supported in your region)3.网络安全组(NSG)
添加NSG规则以控制流量:
// Network Security Group (add to resources.bicep)
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-05-01' = {
name: 'nsg-containerapp'
location: location
tags: tags
properties: {
securityRules: [
{
name: 'AllowHTTPSInbound'
properties: {
priority: 100
direction: 'Inbound'
access: 'Allow'
protocol: 'Tcp'
sourcePortRange: '*'
destinationPortRange: '443'
sourceAddressPrefix: 'Internet'
destinationAddressPrefix: '*'
}
}
{
name: 'DenyAllInbound'
properties: {
priority: 1000
direction: 'Inbound'
access: 'Deny'
protocol: '*'
sourcePortRange: '*'
destinationPortRange: '*'
sourceAddressPrefix: '*'
destinationAddressPrefix: '*'
}
}
]
}
}
// Associate NSG with Container App subnet
resource vnet 'Microsoft.Network/virtualNetworks@2023-05-01' = {
// ... existing properties
properties: {
// ... existing properties
subnets: [
{
name: 'subnet-containerapp'
properties: {
addressPrefix: '10.0.0.0/23'
networkSecurityGroup: {
id: nsg.id
}
delegations: [
{
name: 'Microsoft.App/environments'
properties: {
serviceName: 'Microsoft.App/environments'
}
}
]
}
}
]
}
}4.Azure前门或应用程序网关
对于具有WAF保护的生产级入口:
// Azure Front Door with WAF (add to resources.bicep)
resource frontDoor 'Microsoft.Cdn/profiles@2023-05-01' = {
name: 'fd-${uniqueString(resourceGroup().id)}'
location: 'global'
tags: tags
sku: {
name: 'Premium_AzureFrontDoor' // Premium includes WAF
}
properties: {
originResponseTimeoutSeconds: 60
}
}
// WAF Policy
resource wafPolicy 'Microsoft.Network/FrontDoorWebApplicationFirewallPolicies@2022-05-01' = {
name: 'waf${uniqueString(resourceGroup().id)}'
location: 'global'
tags: tags
sku: {
name: 'Premium_AzureFrontDoor'
}
properties: {
policySettings: {
enabledState: 'Enabled'
mode: 'Prevention'
requestBodyCheck: 'Enabled'
}
managedRules: {
managedRuleSets: [
{
ruleSetType: 'Microsoft_DefaultRuleSet'
ruleSetVersion: '2.1'
}
{
ruleSetType: 'Microsoft_BotManagerRuleSet'
ruleSetVersion: '1.0'
}
]
}
}
}
// Front Door Endpoint
resource fdEndpoint 'Microsoft.Cdn/profiles/afdEndpoints@2023-05-01' = {
parent: frontDoor
name: 'endpoint-${uniqueString(resourceGroup().id)}'
location: 'global'
properties: {
enabledState: 'Enabled'
}
}
// Origin Group (Container Apps)
resource originGroup 'Microsoft.Cdn/profiles/originGroups@2023-05-01' = {
parent: frontDoor
name: 'containerapp-origins'
properties: {
loadBalancingSettings: {
sampleSize: 4
successfulSamplesRequired: 3
additionalLatencyInMilliseconds: 50
}
healthProbeSettings: {
probePath: '/health'
probeRequestType: 'GET'
probeProtocol: 'Https'
probeIntervalInSeconds: 30
}
sessionAffinityState: 'Enabled' // Sticky sessions
}
}
// Origins (one for each Container App instance)
resource origin0 'Microsoft.Cdn/profiles/originGroups/origins@2023-05-01' = {
parent: originGroup
name: 'origin-0'
properties: {
hostName: containerApp[0].properties.configuration.ingress.fqdn
httpPort: 80
httpsPort: 443
originHostHeader: containerApp[0].properties.configuration.ingress.fqdn
priority: 1
weight: 1000
enabledState: 'Enabled'
}
}
// Repeat for other instances...
// Route
resource route 'Microsoft.Cdn/profiles/afdEndpoints/routes@2023-05-01' = {
parent: fdEndpoint
name: 'api-route'
properties: {
originGroup: {
id: originGroup.id
}
supportedProtocols: ['Https']
patternsToMatch: ['/*']
forwardingProtocol: 'HttpsOnly'
linkToDefaultDomain: 'Enabled'
httpsRedirect: 'Enabled'
}
dependsOn: [
origin0
]
}
// Associate WAF with Endpoint
resource wafAssociation 'Microsoft.Cdn/profiles/securityPolicies@2023-05-01' = {
parent: frontDoor
name: 'waf-policy'
properties: {
parameters: {
type: 'WebApplicationFirewall'
wafPolicy: {
id: wafPolicy.id
}
associations: [
{
domains: [
{
id: fdEndpoint.id
}
]
patternsToMatch: ['/*']
}
]
}
}
}
// Output the Front Door URL
output frontDoorUrl string = 'https://${fdEndpoint.properties.hostName}'5.诊断设置和监测
启用全面日志记录:
// Diagnostic Settings for Container Apps (add to resources.bicep)
resource diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [for i in range(0, containerAppInstances): {
name: 'diag-containerapp-${i}'
scope: containerApp[i]
properties: {
workspaceId: logAnalytics.id
logs: [
{
category: 'ContainerAppConsoleLogs'
enabled: true
retentionPolicy: {
enabled: true
days: 30
}
}
{
category: 'ContainerAppSystemLogs'
enabled: true
retentionPolicy: {
enabled: true
days: 30
}
}
]
metrics: [
{
category: 'AllMetrics'
enabled: true
retentionPolicy: {
enabled: true
days: 30
}
}
]
}
}]
// Alert Rules
resource cpuAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = {
name: 'alert-high-cpu'
location: 'global'
tags: tags
properties: {
description: 'Alert when CPU usage exceeds 80%'
severity: 2
enabled: true
scopes: [
containerApp[0].id
containerApp[1].id
containerApp[2].id
]
evaluationFrequency: 'PT5M'
windowSize: 'PT15M'
criteria: {
'odata.type': 'Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria'
allOf: [
{
name: 'HighCPU'
metricName: 'UsageNanoCores'
operator: 'GreaterThan'
threshold: 80
timeAggregation: 'Average'
}
]
}
actions: [] // Add action groups here
}
}生产部署检查表
安全:
- \[\]启用了ExpressRoute集成
- \[\]为存储、密钥库、ACR配置了专用端点
- \[\]后端服务上的公共网络访问已禁用
- \[\]已配置并测试NSG规则
- \[\]已部署Azure前门或应用程序网关
- \[\]在预防模式下启用WAF
- \[\]使用管理身份(无客户端机密)
- \[\]审查并最小化RBAC权限
- \[\]强制执行TLS 1.2最低版本
监控:
- \[\]所有资源上都启用了诊断设置
- \[\]已配置日志分析工作区
- \[\]已连接应用程序洞察
- \[\]为关键指标配置了警报规则
- \[\]为通知创建的操作组
- \[\]为仪表板创建的工作簿
高可用性:
- \[\]多个容器应用程序实例(至少3个)
- \[\]已配置健康探测器
- \[\]会话关联已启用(如果有状态)
- \[\]已配置自动缩放规则
- \[\]跨区域部署(可选)
顺从:
- \[\]已启用静态数据加密
- \[\]强制执行传输中的数据加密
- \[\]已启用审核日志记录
- \[\]备份和灾难恢复计划
- \[\]已安排访问审查
- \[\]已应用合规标签
成本优化技巧
默认部署适用于生产环境,但可以进行优化:
- 容器应用程序扩展
scale: {
minReplicas: 1 // Lower for dev, 2-3 for prod
maxReplicas: 10
rules: [
{
name: 'http-rule'
http: {
metadata: {
concurrentRequests: '100'
}
}
}
]
}- API管理SKU
- 开发者:每月50美元-仅限非生产 - 基础:150美元/月-轻生产工作量 - 标准:700美元/月-生产工作量 - 高级:3000美元/月-企业,多地区
- 集装箱登记处
- 基础:$5/月-小型项目 - 标准:20美元/月-团队项目 - 高级:每月50美元-地理复制,高吞吐量
- 存储帐户
- 使用生命周期策略存档旧日志 - 启用软删除,缩短保留时间
许可证
麻省理工学院
