Agent 继续执行
await client.continue_task({
"task_id": "task-uuid-123",
"resume_from": "stage-2"
})
这个机制让 AI Agent 可以像人类一样"边做边问",而不需要在上一步就把所有信息都问清楚。
---
## 五、证据链与可追溯:从"说了什么"到"依据能否还原"
### 5.1 企业场景的证据需求
在企业级 AI 应用中,AI 给出的结论往往需要被审计和追溯。考虑以下场景:
**场景:银行信贷审批**
信审员使用 AI Agent 辅助审查一家供应商的资质。AI 给出了"该供应商存在重大法律风险,建议拒绝"的结论。
三个月后,供应商投诉:"凭什么拒绝我们?" 信审员需要回答:
- AI 的结论基于哪些数据?
- 数据的时间点是什么?
- 有没有可能数据已经过期?
**旧版 MCP 的问题**:工具调用结果只返回自然语言数据,没有任何元信息可以追溯。
**新版 MCP 的改进**:每个工具调用结果都携带结构化的证据元信息。
```json
// v0.28+ 工具调用结果(带证据元信息)
{
"result": {
"data": {
"company_name": "企查查科技股份有限公司",
"credit_code": "91110108MA01XXXXX",
"risk_level": "high",
"litigation_count": 23,
"penalty_count": 5
},
"_meta": {
"evidence_id": "evidence-uuid-789",
"data_source": "qcc_mcp_business_data",
"query_timestamp": "2026-07-26T07:00:00+08:00",
"data_timepoint": "current",
"confidence": 0.95,
"fields_used": ["litigation_count", "penalty_count", "risk_level"],
"raw_response_hash": "sha256:abc123...",
"limitations": [
"仅覆盖中国大陆司法数据",
"行政处罚数据可能存在 7 天更新延迟"
]
}
}
}
5.2 完整 JSON Schema 的生产价值
2026-07-28 规范将工具的输出 Schema 升级到完整的 JSON Schema 2020-12,这不只是格式升级,而是让结构化交付成为可能。
旧版 Schema(简化):
{
"type": "object",
"properties": {
"company_name": {"type": "string"},
"risk_level": {"type": "string"}
}
}
新版 Schema(完整):
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"company_name": {
"type": "string",
"description": "企业名称"
},
"risk_level": {
"type": "string",
"enum": ["low", "medium", "high", "critical"],
"description": "综合风险等级"
},
"litigation_count": {
"type": "integer",
"minimum": 0,
"description": "当前有效诉讼数量"
},
"last_updated": {
"type": "string",
"format": "date-time",
"description": "数据更新时间"
}
},
"required": ["company_name", "risk_level", "last_updated"],
"additionalProperties": false
}
完整 Schema 的价值在于:
- 客户端可以自动验证返回数据的完整性
- AI Agent 可以知道哪些字段是必填的、哪些是可选的
- 可以自动生成类型安全的客户端代码
- 数据质量可以被系统化地监控
5.3 链路追踪:W3C Trace Context 集成
新版 MCP 引入了 W3C Trace Context 标准,让每次工具调用都可以被纳入分布式追踪体系:
# 工具调用时注入链路追踪上下文
result = await client.call_tool(
"risk_scan",
{"company_id": "qcc-123"},
trace_context={
"traceparent": "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01",
"tracestate": "congo=t61rcWkgMzE"
}
)
# 链路追踪结构
trace = {
"trace_id": "0af7651916cd43dd8448eb211c80319c",
"span_id": "b7ad6b7169203331",
"parent_span_id": "a1b2c3d4e5f6", # 调用方 span
"duration_ms": 234,
"tools_in_chain": [
"company_anchor",
"risk_scan",
"litigation_query",
"penalty_query"
],
"tokens_used": 18432,
"errors": []
}
对于企业级部署,这意味着:
- 可以精确分析每次 AI 推理的耗时分布(哪个工具最慢?)
- 可以发现工具调用链中的错误和异常
- 可以审计每次 AI 决策背后的完整数据路径
- 可以对比不同 AI 模型在同一任务上的表现差异
六、企业级 MCP 架构:实战设计模式
6.1 一个完整的企业 MCP 部署架构
基于 2026-07-28 规范,一个生产级的 MCP 部署架构大概是这样的:
┌──────────────────────────────────────────────────────────────────────┐
│ 客户端层 │
│ Claude Desktop | Cursor | 自定义 Agent | 第三方平台 │
└──────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────┐
│ MCP Gateway(Envoy/Kong) │
│ • JWT 鉴权 & 租户隔离 │
│ • 限流(per-tenant, per-tool) │
│ • 链路追踪(OpenTelemetry) │
│ • 请求路由(根据 tool/server 分发) │
│ • 响应缓存(基于 cacheTtlMs) │
│ • 成本计量(per-tool-cost tracking) │
└──────────────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐
│ Business MCP │ │ Legal MCP │ │ DocParse MCP │
│ Server │ │ Server │ │ Server │
│ ───────────── │ │ ───────────── │ │ ───────────── │
│ 185 tools │ │ 10 tools │ │ 2 tools │
│ (company/risk/ │ │ (laws/cases/ │ │ (PDF→struct/ │
│ ip/opera...) │ │ citations) │ │ doc→struct) │
└───────────────────┘ └───────────────────┘ └───────────────────┘
│ │ │
▼ ▼ ▼
┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐
│ 企业数据源 │ │ 法律数据库 │ │ 文档存储 │
│ (工商/司法/ │ │ (裁判文书/ │ │ (PDF/Word/ │
│ 知识产权/...) │ │ 法规/...) │ │ Excel) │
└───────────────────┘ └───────────────────┘ └───────────────────┘
6.2 无状态 Server 的实现模式
在 2026-07-28 规范下,MCP Server 应该是完全无状态的。这意味着:
# 错误示范:Server 中存储会话状态
class MCPStatefulServer:
def __init__(self):
self.sessions = {} # ❌ 不应该在 Server 中维护会话状态
self.cache = {} # ❌ 不推荐:限制水平扩容
async def handle_request(self, request):
session_id = request.headers.get("Mcp-Session-Id") # ❌ v0.28 已移除
if session_id in self.sessions:
return self.sessions[session_id]
# 正确示范:无状态 Server
class MCPStatelessServer:
def __init__(self, redis_url: str, upstream_db: str):
self.redis = aioredis.from_url(redis_url) # ✅ 状态外置到 Redis
self.db = create_db_pool(upstream_db)
# ✅ 无本地状态,可水平扩展
async def handle_request(self, request: MCPRequest) -> MCPResponse:
# 每个请求自包含所有必要信息
trace_id = request.meta.trace_id # 从请求中获取链路 ID
tenant_id = request.meta.tenant_i