这篇适合谁,读完能做什么
这篇适合已经能在本地跑通智能体、想把它部署给真实用户的开发者。读完后,你应该能区分三种部署方式,理解智能体生命周期里评测门禁的位置,并知道怎样给线上端点加冒烟测试。
从原型到生产,变的是什么
原型智能体和生产智能体的核心循环相同:推理、调用工具、给出回答。不同的是包在这个循环外面的东西。一般估计,模型只占生产智能体的两成左右,其余部分是运维骨架[1]。
具体来说,两者在几个方面不同[1]:
| 方面 | 原型 | 生产 | | --- | --- | --- | | 托管 | 跑在笔记本里 | 作为托管服务,有版本,可以分批发布 | | 身份 | 个人的 az login 令牌 | 带有限定 RBAC 的托管身份 | | 状态 | 在内存里,重启就丢 | 外置到线程存储或记忆服务 | | 故障 | 直接看报错 | 重试、降级、死信队列和告警 | | 成本 | 按每次几分钱估算 | 按请求统计、路由、缓存和预算 | | 质量 | 人工看输出 | 每次发布前自动评测 | | 信任 | 每个动作都由你批准 | 策略加上高风险动作的人工审批 |
后面的每一节,基本都对应表中的某一行。
三种部署方式
实际中会用到三种部署方式,常常组合使用[1]。
第一种是客户端托管。智能体对象运行在你自己的应用进程里,代码直接调用模型服务商,推理循环也在你的服务里跑。扩展、状态和容错都要自己负责[1]。
第二种是 Hosted Agent,即 Foundry Agent Service 托管的智能体。智能体在 Microsoft Foundry 里注册为一个资源,推理循环、线程存储、内容安全和 RBAC 都由 Foundry 负责,并且能在 Foundry 门户里看到。你的应用变成一个轻量客户端,只负责创建线程和读取回复。
第三种是智能体工作流。多个智能体和工具被组织成一张带明确控制流的图,可以有顺序步骤、分支、人工审批节点,以及能暂停和恢复的持久检查点[1]。
生命周期:评测是门禁,不是事后补救
在 Microsoft Foundry 上,智能体的生命周期分为六个阶段:创建、版本管理、部署、评测、观测和下线[1]。部署不是一次性的推送,而是一个循环,很像软件的发布流程。
离线评测是门禁。新版本只有通过评测阈值才能发布。上线后的观测数据,又会把真实世界里的失败案例反馈回离线测试集[1]。
扩展:无状态、路由、缓存和限流
智能体的扩展和普通的无状态 Web API 不一样,因为每个请求都可能触发好几次昂贵的模型调用和工具调用[1]。下面四种手段承担了大部分负载。
无状态处理是指进程内存里不保存任何用户状态。会话线程存进 Foundry 的线程存储或记忆服务,这样任何一个实例都能处理任何请求,水平扩展时不需要粘性会话[1]。
模型路由是指简单请求,比如意图分类和简短的事实问答,交给小而快的模型;只有真正需要推理的请求才交给大模型。Foundry 的 Model Router 可以完成这件事,也可以自己写一个轻量分类器[1]。
响应缓存是指把常见问题的答案存下来,比如「怎么重置密码」,之后直接返回,不再调用模型。即使缓存命中率不高,也能明显降低成本和延迟[1]。
并发和背压方面,模型服务商有速率限制,所以要限制并发数,用指数退避重试,并在失败时优雅降级,比如先返回一条排队提示,而不是报 500 错误[1]。
线上观测:把每一步都变成 span
智能体的运行过程要能被看见,才能运维。Microsoft Agent Framework 原生输出 OpenTelemetry 追踪数据,每一次模型调用、工具调用和编排步骤都会变成一个 span[1]。
把这些 span 导出到 Microsoft Foundry 或任何兼容 OpenTelemetry 的后端,可以做三件事:追踪一条客户投诉从头到尾经过的每次模型和工具调用;观察 p50、p95 延迟和每次请求的成本变化;在错误率飙升或成本异常之前发出告警[1]。
下面的代码在请求外面包了一层 span,并添加了业务属性:
from agent_framework.observability import get_tracer
tracer = get_tracer()
with tracer.start_as_current_span("support_request") as span:
span.set_attribute("customer.tier", "enterprise")
span.set_attribute("routed.model", "gpt-5-nano")
# agent execution is traced automatically inside this spancustomer.tier、routed.model 这类属性,决定了你能不能回答具体的业务问题,比如企业客户是不是被路由到小模型的次数太多了[1]。
成本:先换小模型,再路由,最后大力缓存
生产智能体的成本主要由 token 决定。降本有三个杠杆,按影响大小排列[1]:
- 选对模型规模。通过评测门禁的小模型,通常比大模型便宜,关键是用评测证明小模型够用,而不是因为谨慎就默认用最大的模型。
- 按复杂度路由,只有需要大模型推理的请求才付大模型的价格。
- 积极缓存。最便宜的模型调用,就是那次没有发生的调用。
评测门禁和成本控制其实是同一件事的两面:评测给出质量底线,路由和缓存则尽量让成本贴近这条底线。
企业治理:权限、审批和 MCP
治理方面,Hosted Agent 继承 Foundry 的 RBAC、内容安全和审计日志。每个智能体应该有一个托管身份,只给它必需的最小权限,比如对知识库只读,对工单系统只开放指定接口[1]。
人工审批用于高风险动作,例如超过阈值的退款,需要人工批准后才执行。Microsoft Agent Framework 支持需要审批的工具:智能体提出动作,执行暂停,人工批准或拒绝,然后工作流恢复[1]。
MCP 让智能体通过统一接口使用外部工具。生产中要把每个 MCP 服务器都当作不可信的边界:固定服务器版本,用限定范围的身份运行,校验它返回的结果,并且绝不把密钥交给它。MCP 服务器是依赖项,依赖就要打补丁、做审计,也要限流[1]。
动手实验:一个能上线的客服智能体
实验是一个 Contoso 客服智能体,代码在 notebook code_samples/16-python-agent-framework.ipynb 里[1]。它把生产环境要考虑的几件事都接上了:查询订单状态和提交工单的工具调用;基于 Azure AI Search 知识库的 RAG,并提供内存版的备用方案,让 notebook 不依赖搜索资源也能运行;跨轮次的记忆;按复杂度路由模型;响应缓存;超过阈值的退款需要人工批准;一个离线评测集充当发布门禁;以及 OpenTelemetry 追踪[1]。
请求处理的核心是路由加缓存:
async def handle_support_request(query: str, customer_id: str) -> str:
# 1. Serve from cache when we can.
cached = response_cache.get(normalize(query))
if cached:
return cached
# 2. Route by complexity to control cost.
model = "gpt-5-nano" if is_simple(query) else "gpt-5-mini"
# 3. Run the agent inside a trace span for observability.
with tracer.start_as_current_span("support_request") as span:
span.set_attribute("routed.model", model)
span.set_attribute("customer.id", customer_id)
response = await support_agent.run(query, model=model)
# 4. Cache and return.
response_cache.set(normalize(query), response.text)
return response.text发布前的评测门禁是这样的:
async def evaluation_gate(agent, test_cases, threshold: float = 0.8) -> bool:
passed = 0
for case in test_cases:
result = await agent.run(case["input"])
if score_response(result.text, case["expected"]) >= 0.8:
passed += 1
pass_rate = passed / len(test_cases)
print(f"Evaluation pass rate: {pass_rate:.0%} (gate: {threshold:.0%})")
return pass_rate >= threshold # only deploy if the gate passes门禁函数会返回是否通过,只有通过时才应该部署[1]。
冒烟测试:部署成功不等于能回答
离线评测是对智能体对象运行的。智能体部署成托管端点之后,还需要一项更轻量的检查:端点真的在回答吗?[1]
部署「成功」只能说明控制平面接受了定义。缺少依赖、模型路由配置错误或连接过期,都可能让部署显示成功,但实际不返回任何内容。冒烟测试可以在几秒钟内发现这类问题,每次部署都应该运行[1]。
实验仓库提供了基于 AI Smoke Test GitHub Action 的冒烟测试流水线。测试用例放在 tests/lesson-16-smoke-tests.json 里,包含 Contoso 客服智能体的提示词和断言[1]。工作流用 Azure OIDC 登录,把每条提示词发送到智能体的 Responses 端点,只要有一条断言不通过就让任务失败[1]。配置的核心如下:
- name: Smoke-test hosted agent
uses: JFolberth/ai-smoketest@v1
with:
project_endpoint: ${{ inputs.project_endpoint }}
agent_name: ContosoSupportAgent
tests_file: tests/lesson-16-smoke-tests.json运行这个流水线的联合身份(federated identity)需要在 Foundry 项目范围内拥有 Azure AI User 角色[1]。
三层测试各管什么
冒烟测试、离线评测和线上评测各有分工[1]:
- 冒烟测试回答「能不能访问、能不能回答」,每次部署都跑。
- 离线评测回答「够不够好、能不能上线」,在晋级前运行。
- 线上评测回答「线上表现如何」,持续运行。
下一步
建议先把端点跑通,再用评测门禁和冒烟测试把检查接进发布流程,让每次部署都有依据。
本文改编自 Microsoft 开源课程《AI Agents for Beginners》第 16 课[1],原文以 MIT 许可证发布。
来源
- 1Deploying Scalable Agents with Microsoft FoundryMicrosoft ai-agents-for-beginners (MIT)
引用本页: 可扩展的智能体部署. TellWorld, https://www.tellworld.net/zh/practice/practice-agents-deploy-scalable. 更新于 2026-11-14