☰
strands-agents Python SDK v0.1.5 技术解析:动态 System Prompt 覆盖、推理文本回调与滑动窗口上下文管理的实战演进
2026/9/27 6:48:52 网站建设 项目流程
  • 人工智能
  • 大模型
  • 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.

项目地址:https://gitcode.com/GitHub_Trending/sdkpython13/harness-sdk
点击查看免费下载

导读

本文基于开源仓库中的 Python SDK 变更记录 python/v0.1.5(发布于 2025-05-26,包名strands-agents),逐条拆解该版本的核心变更:动态 System Prompt 覆盖、推理(reasoning)文本进入回调处理器、SlidingWindowConversationManager的重大升级、事件循环重构、Agent.stream_async()的 OpenTelemetry Span 生命周期修复,以及 OpenAI 模型请求格式化的兼容性修复。读完本文,你将掌握如何在生产代码中按调用覆盖系统提示词、消费流式推理文本、精细调优滑窗上下文管理策略,并理解这些能力背后的源码实现与测试验证路径。

一、版本概览:v0.1.5 的定位与变更全景

python/v0.1.5是strands-agentsPython SDK 在 2025-05-26 发布的一个功能与稳定性并重的版本。根据 pyproject.toml 的配置,包名为strands-agents,版本号由 git tag 动态生成(dynamic = ["version"]),且 hatch 的tag_regex = "^python/v(?P<version>.+)$"与变更日志中的tag: python/v0.1.5一一对应——即该版本对应仓库中的python/v0.1.5标签。

本版本共包含 12 条变更记录,按类型归纳如下:

类型数量涉及范围
feat(新功能)3handlers(推理文本回调)、动态 System Prompt 覆盖、SlidingWindowConversationManager 更新
fix(修复)3OpenAI 模型 tool arguments、README logo 配色、stream_async()agent span 生命周期
docs(文档)4README 徽章、logo、标题规范化、仓库链接
other(其他)2事件循环重构、版本发布

其中三项新功能(PR 108、PR 109、PR 120)分别由三位新贡献者Shubhamraut01、josephgultekin、Unshure提交,是本次版本的重点。下面按功能主题深入展开。

二、按调用覆盖 System Prompt:动态系统提示词能力(PR 108)

2.1 使用方式:从"构造时固定"到"调用时动态"

Agent在构造时通过system_prompt参数设定模型行为基线,这属于常规用法。v0.1.5 引入的"动态 System Prompt 覆盖功能"(PR 108)允许在每次调用agent(...)/agent.stream_async(...)时临时传入system_prompt,覆盖 Agent 实例的默认提示词,从而实现同一 Agent 实例在不同任务间切换角色或指令。

以测试 test_agent.py 中的验证逻辑为参照,一次典型的动态覆盖调用形如:

agent( "test message", system_prompt="Override system prompt", # 本次调用临时覆盖默认 system_prompt some_value="a_value", )

测试断言的关键点在于:system_prompt会进入本次调用的invocation_state,事件循环在发起模型请求时读取的是覆盖后的值(invocation_state["system_prompt"] == override_system_prompt),而非 Agent 构造时的默认值。这意味着动态覆盖是按调用生效、不污染实例状态的——下一次不传system_prompt时,仍回落到默认提示词。

2.2 源码实现:setter 与 invocation_state 的配合

从源码结构看,Agent类对系统提示词的管理位于 agent.py:

  • system_prompt是只读属性,返回split_system_prompt(self._system_prompt_content)[0],保证与既有期望字符串接口的代码兼容;
  • system_promptsetter 接受str | list[SystemContentBlock] | None,内部统一转换为_system_prompt_content内容块列表(字符串会被包装为[{"text": ...}]);
  • system_prompt_content属性则返回内容块列表本身,供需要多模态系统块的模型适配层直接消费。

配套测试覆盖了三种 setter 场景:字符串赋值、内容块列表赋值、置None清空(见 test_agent.py)。动态覆盖正是复用这套 setter 语义,在调用路径上把kwargs/invocation_state中的system_prompt透传到事件循环,最终由_start_agent_trace_span(agent.py)连同system_prompt_content一起写入追踪 Span 属性,保证覆盖后的提示词在可观测链路中可追溯。

2.3 典型应用场景

动态覆盖最直接的落地场景包括:

  • 多租户/多角色:同一个 Agent 实例服务不同业务域,按请求切换专家角色提示词;
  • A/B 提示词实验:同一任务批量对比不同 System Prompt 的回复质量,无需重建实例;
  • 会话级定制:结合invocation_state透传的其他上下文(如用户画像、地区配置),在运行时拼装个性化指令。

三、推理文本进入回调处理器:Reasoning 的可观测与终端呈现(PR 109)

3.1 变更内容

PR 109("add reasoning text to callback handler and related tests")让模型输出的推理内容(reasoning text)与签名(signature)能够流入回调事件。此前推理内容只在模型流式层内部流转,外部回调处理器无法感知;v0.1.5 之后,回调事件中新增了reasoning、reasoningText、reasoning_signature字段。

3.2 源码与测试双重佐证

在 callback_handler.py 中,PrintingCallbackHandler.__call__显式读取reasoningText并在终端原样打印:

reasoningText = kwargs.get("reasoningText", False) data = kwargs.get("data", "") complete = kwargs.get("complete", False) ... if reasoningText: print(reasoningText, end="")

配套测试 test_agent.py 精确验证了回调事件携带的字段组合:

unittest.mock.call( agent=agent, delta={"reasoningContent": {"text": "value"}}, ... reasoning=True, reasoningText="value", request_state={}, ) unittest.mock.call( agent=agent, delta={"reasoningContent": {"signature": "value"}}, ... reasoning=True, reasoning_signature="value", request_state={}, )

同时,最终AgentResult.message.content中的推理块以{"reasoningContent": {"reasoningText": {"text": ..., "signature": ...}}}形式完整保留(test_agent.py),说明推理内容不仅在流式过程中可被回调消费,还会随结果消息持久化。

3.3 实战价值

对于部署了带推理能力模型(如 Anthropic 系 reasoning 模型)的 Agent 应用,此变更意味着:

  • 终端交互:PrintingCallbackHandler可在输出最终答案前先行呈现"思考过程",提升可解释性;
  • 自定义回调:自研CompositeCallbackHandler(同文件 callback_handler.py)可将reasoningText分流到日志、审计或分析管道,实现推理链的合规留存。

四、SlidingWindowConversationManager 升级:滑窗、主动压缩与按轮管理(PR 120)

PR 120 对滑动窗口会话管理器做了系统性增强,是 v0.1.5 中与长对话场景最相关的改动。实现位于 sliding_window_conversation_manager.py。

4.1 构造参数全解

SlidingWindowConversationManager( window_size: int = 40, should_truncate_results: bool = True, *, per_turn: bool | int = False, pin_first: int | None = None, proactive_compression: bool | ProactiveCompressionConfig | None = None, )
参数类型/默认值含义与取值说明
window_sizeint,默认40历史消息窗口上限。超过该值才触发缩减;设为0表示每次缩减时清除全部非固定消息。负数会抛ValueError
should_truncate_resultsbool,默认True是否对超大工具结果做部分截断(仅响应式溢出恢复路径生效)
per_turnbool \| int,默认False在 Agent 循环内部主动执行消息管理的时机:False仅在循环结束(finally 块)管理;True每次模型调用前管理;N(正整数)每 N 次模型调用管理一次
pin_firstint \| None,默认None固定对话开头 N 条消息,缩减时受保护不被驱逐
proactive_compressionbool \| ProactiveCompressionConfig \| None,默认None模型调用前的主动压缩:True在上下文窗口使用率达 70% 时压缩;{"compression_threshold": float}自定义阈值(0, 1];False/None关闭,仅保留响应式溢出恢复

4.2 工具结果的智能截断

当上下文溢出(响应式路径,e非空)时,管理器优先从最旧的、含工具结果的消息开始截断(_find_oldest_message_with_tool_results),以最大化保留近期相关上下文。截断策略(_truncate_tool_results)细节:

  • 文本块保留首尾各 200 字符(_PRESERVE_CHARS = 200),中间替换为... [truncated: N chars removed] ...说明性占位;
  • 工具结果中嵌套的图片块被替换为文本占位符,格式如[image: <media_type>, <bytes> bytes],避免图片持续占据上下文预算;
  • 已截断过的文本带... [truncated:标记,不会二次截断。

4.3 合法的裁剪边界:trim point 逻辑

缩减不是简单"砍掉最旧 N 条",而是通过find_valid_trim_point寻找合法边界,保证裁剪后消息序列对模型提供商仍合法(sliding_window_conversation_manager.py):

  1. 边界必须以user 消息开头(大多数模型提供商的要求);
  2. 不能以孤立的toolResult开头;
  3. 不能以toolUse开头,除非其toolResult紧随其后。

值得注意的 Python 特有增强:_find_tool_pair_trim_point提供了兜底路径——当找不到纯 user 消息边界时,回退到assistant(toolUse) + user(toolResult)完整配对边界,因为提供商将完整 toolUse/toolResult 配对视为合法的对话延续。这使得工具密集型对话(如浏览器自动化、多轮检索)也能被正常裁剪,而不会被"无合法边界"卡死。当确实无法缩减时:响应式路径抛ContextWindowOverflowException,主动/例行路径仅记录 warning 并返回。

4.4 per_turn:循环内的主动上下文管理

per_turn是本次升级针对"长循环 Agent"场景的关键能力。其钩子注册在register_hooks(sliding_window_conversation_manager.py),通过监听BeforeModelCallEvent实现;回调内部(_on_before_model_call)维护_model_call_count并按配置决定是否立即执行apply_management。

测试 test_conversation_manager.py 系统验证了该行为:

  • per_turn=False:6 次模型调用期间不触发管理,仅在 finally 块执行一次;
  • per_turn=True:每次模型调用前都管理;
  • per_turn=2:第 2、4、6 次模型调用前各管理一次,另加循环结束一次;
  • per_turn=0或负数抛ValueError。

官方建议(源码 docstring):若 Agent 在循环中执行大量工具操作(如带频繁截图的网页浏览),应启用per_turn=True主动管理历史,防止循环变慢;若性能仍有压力,可调整为per_turn=5之类的频率。

4.5 会话状态持久化

管理器状态支持跨会话恢复:get_state()将model_call_count纳入状态字典(sliding_window_conversation_manager.py),restore_from_session()在恢复时还原计数(同文件 L137-L148),保证per_turn的调度节奏在会话续接后不中断。

五、事件循环重构(PR 106)与 stream_async 的 Span 修复(PR 119)

5.1 "Rise of the Phoenix":事件循环重构

PR 106("🔥🕊️ Rise of the Phoenix: Event Loop Refactor")对 SDK 的核心执行引擎做了重构。当前事件循环实现位于 event_loop.py,职责被清晰划分为多个函数:

  • event_loop_cycle/recurse_event_loop:单轮循环与递归式循环入口;
  • _handle_model_execution:模型调用及流式事件处理;
  • _handle_tool_execution:工具调用与结果回填;
  • _stop_for_interrupts:中断(interrupt)收集与终止决策;
  • _check_limits:按轮次/输出 token/总 token 的预算检查。

从模块结构看,重构后的事件循环将模型执行、工具执行、中断处理解耦为独立阶段,并通过BeforeModelCallEvent/AfterModelCallEvent/BeforeToolsEvent/AfterToolsEvent等钩子对外暴露插桩点,为上文提到的per_turn主动管理、动态 System Prompt 覆盖等能力提供了统一的执行期介入机制。

5.2 agent span 生命周期修复

PR 119 修复了Agent.stream_async()场景下 agent span 的起止问题。在 agent.py 的stream_async实现中可以看到修复后的生命周期编排:

  • 输入消息转换完成后立即self.trace_span = self._start_agent_trace_span(messages)(L1386),并在with trace_api.use_span(self.trace_span)作用域内驱动整个事件循环;
  • 正常结束时self._end_agent_trace_span(response=result)(L1419);
  • 异常路径self._end_agent_trace_span(error=e)(L1424);
  • 取消路径通过end_span_with_cancellation结束(agent.py)。

_start_agent_trace_span(agent.py)会携带agent_name、model_id、tools、system_prompt、system_prompt_content、trace_attributes与完整工具配置,形成包含系统提示词与工具清单的 agent 根 Span;底层实现在 tracer.py(start_agent_span/end_agent_span)。修复后,流式调用全程(含流式结束后的AgentResultEvent回调)都落在正确的 agent span 内,OTLP/console 导出的追踪数据不再出现"有结果无 span"或"span 提前闭合"的错位。

5.3 对可观测性的影响

这一组合(事件循环重构 + span 修复)意味着:使用Agent.stream_async()构建流式应用的团队,可以在 Jaeger、Grafana 等 OTel 后端获得完整的 agent → 模型调用 → 工具调用 span 树,并配合MetricsClient的 usage/metrics 统计定位长会话中的上下文膨胀点。

六、OpenAI 模型适配修复:tool arguments 边界处理(PR 97)

PR 97("models - openai - argument none")属于模型适配层的兼容性修复。从当前源码 openai.py 看,OpenAI 请求格式化通过format_request_message_tool_call将toolUse的输入序列化为工具调用参数:

"arguments": json.dumps(tool_use["input"], ensure_ascii=False),

该修复针对的正是arguments可能为空的边界场景——变更日志记录为argument none。可以推断,修复确保了当模型返回的 tool use 缺少 input 时,请求序列化不会产生非法结构(例如空字符串或None被错误序列化),从而维持 OpenAI API 兼容性。配套消息组装逻辑在 openai.py:仅当存在toolUse内容块时才生成tool_calls字段,且图片块会被从工具消息中拆分为独立 user 消息(_split_tool_message_images,L446-L455),满足 OpenAI 对图片必须位于 user 角色的约束。

七、元数据与文档更新(PR 100–105)

v0.1.5 还包含一组 README 层面的变更(PR 100/101/102/104/105):新增 open PRs 徽章、链接到 samples 示例仓库、将 "Docs" 统一为 "Documentation"、加入 logo,并将 logo 改为跟随用户配色偏好自动切换明暗的方案(先尝试暗色 logo,最终采用随prefers-color-scheme自动变色的实现)。这类变更虽不涉及运行时行为,但对开源项目的可发现性与 README 的可读性有实际价值,也反映了发布流程对仓库门面的一致化治理。

八、升级与验证:让 v0.1.5 落地

8.1 安装

pip install strands-agents==0.1.5

包元数据见 pyproject.toml(name = "strands-agents",版本由 git tagpython/v0.1.5动态解析)。

8.2 行为验证清单

升级后建议重点回归以下路径(仓库自带测试可直接运行验证):

  • 动态 System Prompt:tests/strands/agent/test_agent.py中test_agent__call__with_invocation_state类用例,断言覆盖值进入invocation_state["system_prompt"];
  • 推理回调:同文件 L812-L833 的回调事件断言,验证reasoningText/reasoning_signature字段;
  • 滑窗管理:tests/strands/agent/test_conversation_manager.py中test_per_turn_*系列与test_sliding_window_proactive_compression_skips_tool_result_truncation,覆盖参数校验、钩子注册、按轮调度与主动压缩路径。

8.3 升级注意点

  • per_turn参数有严格的取值约束(0与负整数抛ValueError),迁移旧配置时需确认取值合法;
  • 若依赖回调事件结构,需注意新增的reasoning相关字段是增量字段,不破坏既有data/complete/tool_use语义;
  • 事件循环重构后,若曾自定义中间件或深度依赖内部事件顺序,建议以 event_loop.py 的公开阶段函数为准重新对齐。

结语

v0.1.5 是一次"功能增量 + 引擎加固"并行的版本:动态 System Prompt 覆盖与推理回调让 Agent 的输入与输出都更加可编程;滑动窗口管理器的per_turn、pin_first、proactive_compression三件套为长会话场景提供了可调优的上下文治理方案;事件循环重构与 span 修复则夯实了流式场景下的可观测性底座。对正在用strands-agents构建生产级 Agent 的团队而言,本文涉及的每个能力点都能在仓库源码(agent.py、sliding_window_conversation_manager.py、callback_handler.py、event_loop.py)与对应测试中找到可直接复用的实现范式。

  • 人工智能
  • 大模型
  • 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.

项目地址:https://gitcode.com/GitHub_Trending/sdkpython13/harness-sdk
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询