- 人工智能
- 大模型
- 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 Python SDK(strands-agents)v1.6.0 是一次聚焦于输入模型统一化、多智能体调用体验与 A2A 协议能力扩展的版本迭代。本文以官方变更记录 sdk/python-v1.6.0.md 为核心骨架,结合仓库源码逐条剖析每个改动背后的实现原理:你将掌握AgentInput类型别名的使用方式与多态输入解析逻辑、MultiAgentBase.__call__的同步调用机制、A2A 中FilePart/DataPart的承载方式,以及结构化输出追踪(span)与文件会话管理的安全修复细节,并了解该版本的依赖与工程维护基线。
一、版本概览与发布要点
v1.6.0 发布于 2025-08-26,对应 Git tagpython/v1.6.0。本版本共包含十余项改动,全部为**非破坏性(breaking: false)**变更,核心可归纳为四类:
| 类别 | 代表改动 | 影响面 |
|---|---|---|
| Agent 输入模型 | 新增AgentInputTypeAlias、invoke支持无输入或Message输入、修复 toolUse 块不可序列化参数 | agent |
| 多智能体 | MultiAgentBase新增__call__实现 | multiagent/base.py |
| A2A 协议 | 支持 A2AFileParts与DataParts | multiagent/a2a/executor.py |
| 正确性与安全 | structured_output_span记录时序修复、file_session_manager路径穿越防护 | agent / session 模块 |
| 工程维护 | pydantic 最低版本更新、ruff/pytest 等依赖升级、CI actions 升级 | 依赖与 CI |
以下逐一展开。
二、Agent 输入模型统一:AgentInputTypeAlias 与多态输入解析
2.1AgentInput类型别名的引入与迁移
v1.6.0 先通过 PR #738 新增AgentInput类型别名,随后 PR #746 将其移入types子模块,成为公共类型入口。其定义位于 strands-py/src/strands/types/agent.py#L23:
AgentInput: TypeAlias = str | list[ContentBlock] | list[InterruptResponseContent] | Messages | None这意味着 Agent 的输入统一为五种形态:
str:纯文本提示词;list[ContentBlock]:内容块列表(如文本、图片等多模态块);list[InterruptResponseContent]:中断响应列表,用于恢复被挂起的 agent;Messages:完整的历史消息序列;None:不提供输入(仅依赖会话历史)。
该别名同时被AgentBase协议与LocalAgent的实现共用,例如 agent/base.py#L9-L10 中AgentBase.invoke_async/__call__的prompt参数签名即为prompt: AgentInput = None,从而在类型层面统一了同步、异步与流式三种入口的输入契约。
2.2 多态输入的实际解析逻辑
LocalAgent.invoke_async等入口会将prompt交给_convert_prompt_to_messages进行归一化,其完整实现位于 strands-py/src/strands/agent/agent.py#L1794-L1849。核心分支如下:
- 字符串输入:包装为
[{"role": "user", "content": [{"text": prompt}]}]; - 空列表:直接作为空消息序列;
- 全为 dict 的列表:进一步判断——若元素满足
Message必填键,则视为完整Messages直接并入会话;若元素命中ContentBlock注解键,则包装成一条 user 消息;若元素包含interruptResponse,则抛出明确错误提示(agent 未处于中断状态时不应收到中断响应); None:仅依赖已有会话历史(配合 v1.6.0 的“无输入 invoke”能力);- 其他类型:抛出
ValueError,提示合法输入必须是str | list[ContentBlock] | Messages | None。
此外,该函数还会在会话最后一条消息是toolUse时自动补一条缺失的toolResult消息,以保证发给模型的会话结构合法(对应 PR #568 修复的同一场景)。
2.3 无输入 invoke 与Message输入支持(PR #653)
PR #653 让agent.invoke_async()可以不传任何输入,仅基于内部维护的会话历史继续推理;同时支持直接传入完整的Messages序列作为上下文。这在多轮对话续接、会话恢复与多智能体编排中非常实用——例如恢复一个因中断挂起的任务时,只需保持 agent 实例或通过 session 管理恢复状态,再调用invoke_async()即可。
三、修复 agent 作为工具时的不可序列化参数(PR #568)
当把 Agent 通过as_tool()暴露为工具、供另一个 Agent 调用时,工具调用块(toolUse block)中可能携带无法序列化的参数。v1.6.0 修复了该问题,配合 agent.py#L1803-L1817 中“检测到最新消息为 toolUse 时补全 toolResult”的机制,确保跨 Agent 的工具调用链在序列化与消息补全两个环节都保持合法。使用该能力的典型场景是多智能体嵌套:外层 agent 通过AgentTool调用内层 agent,invoke返回的AgentResult会作为工具结果回填会话。
四、MultiAgentBase.__call__:多智能体的同步调用体验(PR #645)
4.1 实现细节
PR #645 为MultiAgentBase(Swarm、Graph等编排器的公共基类)新增了同步__call__实现,位于 strands-py/src/strands/multiagent/base.py#L309-L327:
def __call__( self, task: MultiAgentInput, invocation_state: dict[str, Any] | None = None, **kwargs: Any ) -> MultiAgentResult: if invocation_state is None: invocation_state = {} if kwargs: invocation_state.update(kwargs) warnings.warn("`**kwargs` parameter is deprecating, use `invocation_state` instead.", stacklevel=2) return run_async(lambda: self.invoke_async(task, invocation_state))值得注意的两点设计:
invocation_state默认值为None(而非可变默认参数{}),规避了 Python 可变默认参数共享状态的经典陷阱;**kwargs进入弃用路径:传入的额外关键字参数会被合并进invocation_state并发出弃用警告,官方推荐统一使用invocation_state传递跨 Agent 的共享上下文。
4.2 使用方式
由此,Swarm / Graph 编排器与LocalAgent保持一致的调用习惯:
from strands.agent import Agent from strands.multiagent.swarm import Swarm agent = Agent(name="worker", model="your-model", system_prompt="...") swarm = Swarm(agents=[agent], ...) # 同步调用(内部通过 run_async 驱动事件循环) result = swarm("帮我完成这个任务", invocation_state={"trace_id": "abc"})五、A2A 协议扩展:FileParts与DataParts(PR #596)
5.1 承载多模态与结构化数据
v1.6.0 让 A2A(Agent-to-Agent)通信支持两种新增 Part 类型:
FilePart:跨 Agent 传输文件内容(文本、二进制等),用于文档分析、代码评审等场景;DataPart:承载结构化 JSON 数据,用于传递非文本的控制信息。
在 strands-py/src/strands/multiagent/a2a/executor.py 中,FilePart与DataPart与TextPart、InternalError、InvalidParamsError等共同构成 A2A 消息Part的联合类型。
5.2DataPart与中断机制的深度集成
源码中一个值得关注的模式:A2A 的中断(interrupt)响应正是通过DataPart承载的。executor 定义了:
INTERRUPT_RESPONSE_KEY = "interruptResponse"当 agent 需要用户输入时,服务端会构造两部分消息:一个TextPart描述需要什么,一个DataPart携带每个中断的id(见 executor.py#L434-L464)。客户端恢复被挂起的任务时,发送形如下面的DataPart即可(见 executor.py#L666-L672):
{"kind": "data", "data": {"interruptResponse": {"interruptId": "<id>", "response": <any>}}}该载荷与 Strands 的InterruptResponseContent类型逐字对齐,注释明确说明“wire 契约与 SDK 类型不允许漂移”。这也解释了AgentInput别名中为何包含list[InterruptResponseContent]——它与 A2A 的中断恢复路径共用同一数据形态。
六、结构化输出追踪(span)修复(PR #709)
PR #709 修复了structured_output_span的事件记录时序:先在 span 上写入 system_prompt,再追加输入消息。对应实现位于 strands-py/src/strands/agent/agent.py#L1051-L1086:
with self.tracer.start_structured_output_span(...) as structured_output_span: ... structured_output_span.set_attributes({ "gen_ai.system": "strands-agents", "gen_ai.agent.name": self.name, "gen_ai.agent.id": self.agent_id, "gen_ai.operation.name": "execute_structured_output", }) if self.system_prompt: structured_output_span.add_event( "gen_ai.system.message", attributes={"role": "system", "content": serialize([{"text": self.system_prompt}])}, ) for message in temp_messages: structured_output_span.add_event( f"gen_ai.{message['role']}.message", ...)时序修复后,gen_ai.system.message事件始终位于各角色消息事件之前,保证追踪数据(trace)中的对话顺序与真实发送给模型的顺序一致,便于后续在 telemetry 中对结构化输出调用做准确的时序分析。structured_output()的调用入口本身支持“传 prompt 则临时使用不写入历史、不传则仅用历史”两种模式(见 agent.py#L989-L1018)。
七、会话安全:file_session_manager路径穿越防护(PR #728)
PR #728 修复了文件型会话管理器(file_session_manager)中message_id可能引发路径穿越(path traversal)的问题:当message_id由外部输入构造文件路径时,恶意构造的../序列可能逃逸会话存储目录。该修复对message_id进行了校验/归一化,防止越界读写。对于以文件持久化会话状态的生产部署,建议在升级后复核所有传入message_id的上游来源,确保其来自受信任的会话上下文。
八、工具执行器(Tool Executors,PR #658)
PR #658 引入 “tool executors” 概念(chore 类别,非破坏性)。结合 strands-py/src/strands/tools 下的实现与 tests 测试,它是对工具执行逻辑的进一步抽象,为后续支持更灵活的工具调度(如异步执行、重试、并发控制)打下基础。对使用者而言,本版本的既有@tool装饰器与ToolRegistry用法保持兼容。
九、工程与依赖维护基线
v1.6.0 同步更新了开发与 CI 依赖,便于复现构建环境:
| 依赖 | 版本范围变化 |
|---|---|
| pre-commit | >=3.2.0,<4.2.0→>=3.2.0,<4.4.0 |
| ruff | >=0.4.4,<0.5.0→>=0.4.4,<0.13.0 |
| pytest-asyncio | >=0.26.0,<0.27.0→>=0.26.0,<1.2.0 |
| pytest-cov | >=4.1.0,<5.0.0→>=4.1.0,<7.0.0 |
| pydantic | 最低版本上调(PR #723) |
| actions/checkout | 4 → 5 |
| actions/download-artifact | 4 → 5 |
其中pydantic 最低版本上调(PR #723)对使用者有直接影响:升级到 v1.6.0 后,需要确保环境中 pydantic 版本满足新的最低要求,否则会出现导入错误。其余为开发工具链与 CI 基础设施升级,另在 pyproject.toml 中维护完整的项目依赖声明。
此外,.gitignore增加了.DS_Store(PR #681),属于仓库卫生维护。
十、新贡献者
本版本迎来两位新贡献者:
- vawsgit(PR #681):
.DS_Store忽略规则; - chengweitsai(PR #709):结构化输出 span 时序修复。
总结与升级建议
Strands Python SDK v1.6.0 以“输入模型统一 + 多智能体调用增强 + A2A 能力扩展”为主线,是一次质量与体验并重的非破坏性迭代:
- 输入侧:
AgentInput别名(types/agent.py)统一了五种输入形态,_convert_prompt_to_messages(agent/agent.py)保证了多态输入的正确归一化与 toolUse 消息补全; - 编排侧:
MultiAgentBase.__call__(multiagent/base.py)让 Swarm / Graph 获得与单个 Agent 一致的同步调用体验,并引导使用invocation_state传递共享上下文; - 协议侧:A2A
FilePart/DataPart支持(multiagent/a2a/executor.py)打通了多模态传输与基于DataPart的中断恢复; - 质量侧:结构化输出 span 时序、文件会话路径穿越、toolUse 参数序列化等修复提升了可观测性与安全性。
升级时请重点关注 pydantic 最低版本要求,并核对会话/message_id相关调用的输入来源;同时可借助本版本新增的MultiAgentBase.__call__与无输入invoke能力,简化多智能体编排与对话续接代码。
- 人工智能
- 大模型
- 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.
相关推荐
为什么你的Godot游戏节点之间沟通不畅?信号机制快速上手指南
为什么你的Godot游戏节点之间沟通不畅?信号机制快速上手指南 当你在用 Godot Engine 开发游戏时,是否遇到过这样的困境:子弹击中了敌人,但计分板毫
人工智能大模型AI AgentAgent 框架多智能体工具调用MCP 服务Easy-Vibe 三阶段 Vibe Coding 学习路径全解:从零基础到 AI 原生产品工程师
Easy Vibe 三阶段 Vibe Coding 学习路径全解:从零基础到 AI 原生产品工程师 Easy Vibe 是一个面向 AI 时代产品构建者的开源编
人工智能大模型AI AgentAgent 框架多智能体工具调用MCP 服务用 Strands SDK 构建多智能体编排系统:Teacher's Assistant 教师助手示例深度解析
用 Strands SDK 构建多智能体编排系统:Teacher's Assistant 教师助手示例深度解析 本文以 strands py 开源仓库中的 mu
人工智能大模型AI AgentAgent 框架多智能体工具调用MCP 服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考