- 人工智能
- 大模型
- AI Agent
- Agent 框架
- 多智能体
- 工具调用
- MCP 服务
【免费下载链接】harness-sdk
Build an agent harness and control it end-to-end. Open-source SDK for production AI agents in Python & TypeScript - any model, any cloud.
本篇基于仓库内 Python SDK 的 v1.39.0 版本变更记录(site/src/content/changelog/sdk/python-v1.39.0.md)成文,聚焦本次发布在模型层(Bedrock / OpenAI 兼容端点)、上下文管理与多智能体 A2A 协议上的关键升级。读完本文,你将掌握use_native_token_count开关、Bedrock 计费 Token 估算的降级与缓存策略、内置上下文窗口查找表的作用机制、MCP 客户端初始化错误的根因排查,以及 A2A 全任务生命周期状态(failed、canceled、input_required 等)在 SDK 中的落地方式,并能直接定位到 strands-py 中对应的源码与测试用例做进一步验证。
版本概览:一次全部非破坏性的功能增强
v1.39.0 发布于 2026-05-08,版本标签为python/v1.39.0,属于sdk(Python SDK)通道的常规迭代。本次共包含 9 条变更,全部为 non-breaking(非破坏性),不存在 API 兼容性破坏,可直接升级使用:
| 类型 | 变更内容 | 涉及领域 |
|---|---|---|
| feat | 支持 OpenAI 提供方使用 AWS Profile | model |
| fix | 在 MCPClientInitializationError 消息中包含根因 | 通用 |
| feat | 新增上下文窗口上限查找表 | context |
| fix | 修复 Bedrock 模型的 Token 计数 | model |
| fix | 缓存不支持 Token 计数的 Bedrock 模型 | 通用 |
| feat | 新增 useNativeTokenCount 开关以跳过 Token 计数 API 调用 | 通用 |
| fix | 修正 MCPClient.exit与 stop() 的类型注解 | 通用 |
| feat | 实现完整的 A2A 任务生命周期状态支持 | a2a |
| fix | 集成测试更新 | 通用 |
其中「Bedrock Token 计数」相关的三条变更(PR 2254 / 2250 / 2255)构成一个完整的闭环:先修复计数逻辑本身,再为不支持计数的模型做缓存降级,最后提供显式开关让用户跳过 API 调用。这也是本版本在模型层最值得关注的组合拳。
OpenAI 提供方支持 AWS Profile:通过 boto_session 接入 Bedrock
本次发布的第一个 feat(PR 2230)是让 OpenAI 兼容提供方能够使用 AWS Profile。其实现载体是openai_responses.py中的bedrock_mantle_config参数,以及内部模块 _openai_bedrock.py 中的BedrockMantleConfig配置结构。
BedrockMantleConfig的关键字段如下(摘自 strands-py/src/strands/models/_openai_bedrock.py):
endpoint:选择端点家族,"bedrock-mantle"(默认)或"bedrock-runtime";仅bedrock-runtime接受跨区域推理配置 ID(如us.openai.*、global.openai.*);region:托管 Bedrock 端点的 AWS 区域,缺省时按 boto3 标准链解析(AWS_REGION/AWS_DEFAULT_REGION/ 活动 Profile / EC2 元数据),全部失败则抛出ValueError;boto_session:本次「支持 AWS Profile」的关键入口。可传入一个用指定 Profile 创建的boto3.Session(如boto3.Session(profile_name="my-profile")),用于在未显式设置region时解析区域,从而无需导出环境变量即可切换到非默认 Profile;credentials_provider:可选 botocoreCredentialProvider,转发给令牌生成器;expiry:可选timedelta,控制 Bearer Token 的生存期。
从源码实现看(strands-py/src/strands/models/_openai_bedrock.py),区域解析优先级为:显式region>boto_session.region_name>boto3.Session()默认链;而resolve_bedrock_client_args(同文件 L141-L191)会调用aws_bedrock_token_generator.provide_token按需铸造 Bearer Token,并将解析结果写入 OpenAI 客户端的base_url与api_key。这样长期运行的 Agent 也能在 Bearer Token 超过最大生命周期后自动续期。
import boto3 from strands.models.openai_responses import OpenAIResponsesModel model = OpenAIResponsesModel( model_id="openai.gpt-5", bedrock_mantle_config={ # 显式指定 AWS Profile,无需导出环境变量 "boto_session": boto3.Session(profile_name="my-aws-profile"), "endpoint": "bedrock-mantle", # 或 "bedrock-runtime" }, )需要注意的是,使用bedrock_mantle_config需要额外安装aws-bedrock-token-generator包,源码中明确提示通过pip install strands-agents[openai]安装;同时client_args中不能再同时传入base_url或api_key,否则会在__init__阶段触发 fail-fast 的冲突校验(见 openai_responses.py)。
Bedrock Token 计数三件套:修复、缓存与开关
v1.39.0 对 Bedrock 的 Token 计数做了系统性收尾,集中在 strands-py/src/strands/models/bedrock.py:
1. 修复 count tokens(PR 2254)
修复了 Bedrock 模型 Token 计数结果不准确的问题。修复后的原生计数路径(bedrock.py)复用与 Converse API 完全相同的消息格式:将messages、system、toolConfig组装进input={"converse": ...},调用client.count_tokens获取inputTokens作为输入 Token 数;若返回值为空则抛出ProviderTokenCountError。
2. 缓存不支持的模型(PR 2250)
并非所有 Bedrock 模型都支持 CountTokens API。当遇到两类典型错误时,SDK 会把该model_id记入模块级缓存_SKIP_COUNT_TOKENS_MODELS,后续调用直接跳过 API并回退到本地启发式估算:
AccessDeniedException(缺少bedrock:CountTokens权限);ValidationException且错误信息包含"doesn't support counting tokens"。
其他瞬时错误(如网络抖动)则不会写入缓存,只做单次降级。相关行为在 tests/strands/models/test_bedrock.py 中有覆盖:测试验证了「第一次调用失败后,第二次调用因缓存而完全跳过 API」的语义(如 L4909 附近的注释)。
3. useNativeTokenCount 开关(PR 2255)
use_native_token_count是本次新增的模型配置项(bedrock.py):
True:count_tokens()调用 Bedrock 原生 CountTokens API 获取精确计数;False(默认):跳过 API 调用,使用本地估算器。
源码逻辑非常直白(bedrock.py):配置不为True时直接走父类本地估算;为True但模型在_SKIP_COUNT_TOKENS_MODELS缓存中时同样回退。换言之,默认行为以低延迟、零额外 API 成本为优先,需要精确计数(例如对成本敏感的生产环境)时再显式开启。
model = BedrockModel( model_id="anthropic.claude-sonnet-4-6", use_native_token_count=True, # 开启后 count_tokens 走 Bedrock CountTokens API )上下文窗口上限查找表:让 context 管理有据可依
PR 2249 新增的上下文窗口查找表位于 strands-py/src/strands/models/_defaults.py,是本次发布在 context 领域的关键支撑。
表结构与默认值
_CONTEXT_WINDOW_LIMITS是一张以模型 ID 为键、以 Token 数为值的内置表,覆盖 Anthropic(直接 API 与 Bedrock 前缀两种形式)、Amazon Nova、Z.AI、OpenAI、Google Gemini、Mistral 等主要模型线。例如:
claude-sonnet-4-6/claude-opus-4-6等:1,000,000 tokens;claude-3-7-sonnet-20250219等:200,000 tokens;amazon.nova-pro-v1:0:300,000;amazon.nova-micro-v1:0:128,000;gpt-4o:128,000;gpt-4.1:1,047,576;gemini-2.5-flash/gemini-2.5-pro:1,048,576;mistral-large-latest:262,144。
当查表失败(未知模型)时,get_context_window_limit返回None,调用方优雅降级(例如禁用主动压缩);同时存在兜底默认值DEFAULT_CONTEXT_WINDOW_LIMIT = 200_000(strands-py/src/strands/models/_defaults.py)。
跨区域前缀剥离
Bedrock 模型 ID 常带有区域/推理配置前缀(如us.anthropic.claude-sonnet-4-6、global.openai.gpt-5.6-luna、eu.、ap.,甚至 ARN)。get_context_window_limit的查找策略是:先做精确匹配,失败后逐点剥离前缀重试(strands-py/src/strands/models/_defaults.py),因此表中只需维护基础模型 ID。这一点在 tests/strands/models/test_defaults.py 中被明确断言:us./global./eu./ap./custom.前缀的模型 ID 都能正确解析到 1,000,000。
与用户配置的合并
resolve_config_metadata(同文件 L178-L199)负责将查表结果写入模型配置:用户显式设置了context_window_limit时原样保留,未设置时才从表自动补全,且仅在确实补上了字段时才返回新 dict,避免无谓的内存分配。
from strands.models._defaults import get_context_window_limit, resolve_config_metadata # 直接查表(含前缀剥离) assert get_context_window_limit("us.anthropic.claude-sonnet-4-6") == 1_000_000 # 合并进模型配置:显式值优先,未设置则自动补全 config = {"model_id": "claude-sonnet-4-6"} merged = resolve_config_metadata(config, "claude-sonnet-4-6") assert merged["context_window_limit"] == 1_000_000该表会为对话管理、上下文压缩、上下文溢出检测(ContextWindowOverflowException)等机制提供统一的窗口基准,是 v1.39.0 在 context 领域的基础设施升级。
MCP 客户端:错误根因透传与类型注解修正
1. 初始化错误携带根因(PR 2238)
此前MCPClientInitializationError只报告笼统的初始化失败,用户难以定位是超时、权限还是连接问题。本次修复让异常消息包含原始根因(root cause),核心改动在 strands-py/src/strands/tools/mcp/mcp_client.py:
# 初始化阶段任意异常,都会把根因拼进消息并用 from e 保留原始异常链 raise MCPClientInitializationError(f"the client initialization failed: {e}") from e对应测试(tests/strands/tools/mcp/test_mcp_client.py)构造了Transport initialization failed场景,断言异常消息精确匹配the client initialization failed: Transport initialization failed。除此之外,超时场景也会得到专门的提示(background thread did not start in {startup_timeout} seconds,见 mcp_client.py),异常类本身定义在 strands-py/src/strands/types/exceptions.py。
2.exit与 stop() 类型注解修正(PR 2248)
本次还修正了MCPClient.__exit__与stop()的类型注解。从源码看(mcp_client.py),__exit__声明返回None并委托self.stop(exc_type, exc_val, exc_tb);stop的三个形参分别对应异常类型、异常值与 traceback(mcp_client.py),并负责信号通知后台线程、等待 join、按序清理事件循环与各项状态、支持实例复用。修正后的注解与contextlib.AbstractContextManager约定一致,让类型检查器(mypy / pyright)不再误报。
A2A 全任务生命周期状态支持
PR 2245 实现了 A2A 协议的完整任务生命周期支持,涉及 strands-py/src/strands/multiagent/a2a/executor.py 与 strands-py/src/strands/multiagent/a2a/_converters.py。
StrandsA2AExecutor将 Strands Agent 适配为 A2A 协议执行器,流式模式下支持failed(失败)、canceled(取消)、以及基于 interrupt 的 input_required(需要输入)等完整生命周期状态(executor.py)。状态到 Agent 停止原因的映射定义在_converters.py中:
_STATE_TO_STOP_REASON: dict[TaskState, StopReason] = { TaskState.completed: "end_turn", TaskState.failed: "end_turn", TaskState.canceled: "end_turn", TaskState.rejected: "end_turn", TaskState.input_required: "interrupt", TaskState.auth_required: "interrupt", }也就是说,A2A 的input_required/auth_required状态会映射为 Strands 的中断(interrupt)语义,驱动 Agent 暂停并请求人工输入或鉴权,而不是直接终止;failed/canceled/rejected则正常结束回合。执行器还支持按context_id隔离会话状态,并推荐使用agent_factory(每个 context 一个独立 Agent、独立锁、可并发执行)而非已废弃的单一agent复用模式。相关集成测试位于 tests_integ/a2a/ 与 tests_integ/test_a2a_executor.py。
集成测试更新与升级建议
PR 2262 对集成测试做了同步更新,确保上述模型层与 A2A 改动在真实端到端场景(见 tests_integ/)中持续得到验证。
升级到 v1.39.0 时的实操要点:
- 无破坏性变更,可直接升级;
use_native_token_count、context_window_limit均为可选项,默认行为(本地估算、自动查表补全)保持不变; - 需要精确 Token 计数且模型受支持时,显式开启
use_native_token_count=True; - 需要按自定义窗口管理上下文时,显式设置
context_window_limit,它会覆盖内置查找表; - OpenAI 兼容端点接入 Bedrock 时,通过
bedrock_mantle_config传入带profile_name的boto_session即可复用 AWS Profile,需安装strands-agents[openai]额外依赖; - 若 MCP 服务器初始化失败,v1.39.0 的异常消息会直接携带根因,配合
from e保留的原始异常链即可快速定位。
本文涉及的实现均可继续在仓库中追溯:模型层见 strands-py/src/strands/models/,MCP 客户端见 strands-py/src/strands/tools/mcp/mcp_client.py,A2A 见 strands-py/src/strands/multiagent/a2a/,对应单测与集成测试分别在 strands-py/tests/strands/models/test_bedrock.py、strands-py/tests/strands/models/test_defaults.py、strands-py/tests/strands/tools/mcp/test_mcp_client.py 与 strands-py/tests_integ/a2a/ 中。
- 人工智能
- 大模型
- AI Agent
- Agent 框架
- 多智能体
- 工具调用
- MCP 服务
【免费下载链接】harness-sdk
Build an agent harness and control it end-to-end. Open-source SDK for production AI agents in Python & TypeScript - any model, any cloud.
相关推荐
strands-agents Python SDK v1.34.1 版本更新解读:上下文 Token 追踪、Langfuse 环境变量隔离与 Span 生命周期修复
strands agents Python SDK v1.34.1 版本更新解读:上下文 Token 追踪、Langfuse 环境变量隔离与 Span 生命周期
人工智能大模型AI AgentAgent 框架多智能体工具调用MCP 服务harness-sdk Python SDK v1.9.0 版本详解:OpenTelemetry 缓存指标、可配置 Swarm 入口点与 MCP 生命周期修复
harness sdk Python SDK v1.9.0 版本详解:OpenTelemetry 缓存指标、可配置 Swarm 入口点与 MCP 生命周期修复
人工智能大模型AI AgentAgent 框架多智能体工具调用MCP 服务MCP Python SDK 服务生命周期(Lifespan)实战:初始化、清理与类型化上下文
MCP Python SDK 服务生命周期(Lifespan)实战:初始化、清理与类型化上下文 导读 真实的 MCP 服务器几乎总是要在整个运行期间持有某些资源
人工智能MCP 服务MCP Clients
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考