Strands Agents与模型驱动方法:构建自主思考的AI代理

本文介绍了AWS开源的Strands Agents SDK采用的模型驱动方法,通过让大型语言模型自主决策工具使用和任务编排,构建能够动态适应各种场景的智能代理系统,涵盖单代理与多代理协作模式。

直到最近,构建AI代理仍然意味着需要应对复杂的编排框架。开发人员需要编写精细的状态机、预定义工作流和大量的错误处理代码,以指导语言模型完成多步骤任务。我们需要构建复杂的决策树来处理“如果API调用失败怎么办?”或“如果用户提出意外问题怎么办?”等问题。尽管付出了这些努力,当代理遇到未预料到的情况时仍然会崩溃。

Strands Agents SDK采用了模型驱动方法,完全消除了这种脆弱性。我们不再试图预测并为所有可能的情况编写代码,而是让现代大型语言模型驱动自身行为,智能决策工具使用,并动态适应任何情况。这种方法更具弹性,因为它让模型能够动态推理问题。当API调用失败时,模型不会崩溃——它会考虑替代方案。当用户提出意外问题时,模型不会遵循预定的“我不理解”路径——它会想办法使用可用工具来提供帮助。模型的推理能力比我们编写的任何状态机都能更好地处理边缘情况。

模型驱动方法源于AWS团队为Kiro、Amazon Q Developer和AWS Glue构建生产代理的实际经验。我们的发现彻底改变了我们对代理架构的思考方式:我们为早期模型构建的编排框架现在反而阻碍了现代LLM自然能力的发挥。

然而,使用模型作为编排器并不意味着牺牲开发人员的控制权。Strands提供了一个清晰简单的接口,让您能在几分钟内上手,同时在需要时提供强大的可配置性。内置的评估工具帮助您理解和验证代理行为,确保即使在模型自主决策时也能保持信心。这种简单性和灵活性之间的平衡使得模型驱动方法既适用于快速原型设计,也适用于生产系统。Strands与您共同成长。

在本文中,我们将探讨模型驱动方法如何从实际生产经验中产生,并向您展示构建能够自主思考的代理的实用模式。

当编排成为限制

传统的代理框架出现在语言模型需要大量指导的时代。开发人员构建了精细的状态机、预定义的工作流和复杂的编排逻辑,因为模型无法可靠地推理其后续步骤。我们会编写数百行代码来处理“收集信息”、“分析数据”和“提供响应”之间的流程——但最终仍然得到在用户以意外方式提问时会崩溃的代理。

与我合作构建Amazon Q Developer的AWS团队亲身体验了这一点。我们最初使用传统的编排框架,但产品需求和用户行为的变化需要大量的科学和工程工作来校准系统以处理新的用例。机器学习路由器和分类器会为护栏返回刚性输出——如“抱歉,我无法回答这个问题”之类的静态文本——而不会以有帮助且感觉智能的交互方式提供替代方案或解释。

现代模型已经足够复杂,可以成为自己的编排器。这是改变一切的关键见解。虽然结构化工作流仍然有其位置——特别是对于合规要求或明确定义的业务流程——但模型驱动方法在大多数场景中消除了对刚性编排的需求。

当Q Developer团队转向模型驱动方法时,系统能够动态处理不断变化的产品需求,并且无论遇到什么情况都能连贯地响应。代理不再提供刚性的护栏响应,而是可以提供替代解决方案,并将护栏输出作为上下文,使模型理解为什么不能回答某些输入。这使得多代理系统具有统一的个性和语调,允许亚马逊的工程师贡献他们的专业知识,同时保持连贯性。它还在适当的时间为模型提供了适当的上下文,配备了强大的工具,以提供有帮助的智能响应。

当您为模型提供工具时,它不仅仅是机械地执行它们。它会推理最佳方法,考虑多种策略,并根据发现的内容调整其行为。分析性能问题的模型可能从系统指标开始,意识到瓶颈实际上在数据库中,转向查询分析,然后建议立即修复和长期架构改进——所有这些都不需要为该序列进行显式编程。

运营效益是变革性的。以前需要数月开发的内容现在只需数周。我们的团队可以快速利用最新的大型语言模型功能,如工具调用、扩展和交错思维、多代理系统、元代理、MCP和A2A——同时为开发人员保持简单的接口,可以完全定制用于AI代理的生产部署。

这种理念超越了单个代理。无论您是构建简单的数据分析代理还是复杂的多代理系统,模型都会决定何时与其他代理协作、何时委托任务、何时深入研究问题以及何时提供最终答案。

代理循环:智能与行动的交汇点

这一理念的核心是代理循环——一个推理和行动的自然循环,反映了智能系统如何思考和工作。这种方法建立在ReAct范式的基础上,该范式展示了语言模型如何以交错方式生成推理轨迹和特定任务行动,从而在思考和行动之间创造更大的协同作用。

模型进行持续推理,提出诸如以下问题:

  • “我在这里试图完成什么?”
  • “我需要什么信息?”
  • “哪些工具最有效?”
  • “这些结果如何改变我的理解?”
  • “我应该继续探索还是提供答案?”

这种内部推理过程是模型驱动代理如此强大的原因。它们不仅仅是执行预定义的步骤——它们会实时思考、适应和发展其方法。

通过上下文引导智能

虽然模型驱动自身行为,但该行为是由其接收的上下文塑造的。在模型驱动方法中,您不是通过刚性控制结构来引导代理智能,而是通过精心设计的上下文,包括系统提示、工具规范和对话历史。

可以将其想象为雇佣一名熟练的顾问。您不会微观管理他们的每一步——相反,您给他们清晰的目标,解释可用的资源,并提供相关的背景信息。模型驱动方法的工作方式相同。

系统提示建立代理的角色和目标——它们设置指导所有决策制定的基本身份和高级目标。有效的系统提示不是规定具体步骤,而是描述成功的样子并提供决策原则。与其写“首先检查数据库,然后验证输入,然后处理请求”,您可能会写“您帮助用户高效准确地分析数据,始终在处理前验证输入”。

工具规范定义能力边界和使用指南——它们不仅传达可用的工具,还传达应该如何以及何时使用它们。设计良好的工具描述成为模型推理过程的一部分。像“将此用于需要精度的复杂数学计算”这样的工具描述帮助模型在计算器工具和编写Python代码之间适当选择。

对话历史保持任务连续性和不断发展的上下文——它提供特定细节,允许代理在交互之间保持连贯性。随着对话变长,管理此上下文对于在保留相关信息的同时保持性能变得至关重要。上下文管理对模型驱动代理至关重要——这是保持连贯智能对话的代理与丢失重要细节或超过令牌限制的代理之间的区别。Strands提供了一个简单的接口,让开发人员定义代理系统提示、工具和上下文管理行为,而不会陷入实现复杂性。

滑动窗口方法保留最近的消息并丢弃较旧的消息:简单高效。总结技术在令牌限制内保留较长对话的关键信息——更适合复杂、不断发展的讨论。目标是给模型最相关的上下文,以便为您的特定用例做出良好决策。

这代表了从过程式编程到上下文式编程的重大转变。您不是在编写“如果这样,那么就那样”的逻辑,而是在精心设计帮助模型自己找出最佳方法的上下文。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from strands import Agent
from strands_tools import calculator, file_write, python_repl

# 简单:几秒钟内开始
agent = Agent(
    tools=[calculator, file_write, python_repl],
    system_prompt="您是一个可以执行计算并用代码验证它们的乐于助人的助手。"
)

# 模型自主决定:先计算,然后用代码验证
agent("计算10,000美元以5%年利率复利10年的利息")

这种设计理念贯穿Strands。您可以在不迷失配置的情况下构建复杂的代理,但每个方面在您的用例需要时仍然可定制。

使用Strands扩展模型驱动代理

模型驱动方法自然地扩展,同时保持相同的清晰开发人员体验。配备适当工具的单个代理可以处理传统上需要多个专用组件的复杂任务。当您确实需要多个代理时,模型通过几种经过验证的模式自行协调。Strands为多代理协调提供了四种主要方法,每种方法适用于不同的用例:

  • 代理即工具:专家作为智能工具的分层系统
  • 群组:具有自组织代理团队的自主协作
  • 图:具有确定性执行路径的结构化工作流
  • 元代理:可以修改自身编排行为的动态代理

无论您是构建简单的层次结构还是复杂的自适应系统,Strands都保持接口清洁,同时提供生产系统所需的可配置性。

代理即工具:分层智能

当单个代理需要专业知识时,代理即工具将其他代理转变为智能工具。这创建了自然层次结构,其中编排器代理委托给专家,在每一级利用模型驱动方法的同时保持清晰的职责分离。编排器如何决定咨询哪些专家?模型通过请求进行推理,就像它推理工具选择一样。当用户询问“计划一次去东京的商务旅行并研究那里的市场机会”时,编排器认识到这需要旅行规划和市场研究专业知识。它可能首先咨询旅行顾问以了解物流,然后使用这些约束来指导研究分析师的工作。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from strands import Agent, tool

@tool
def research_analyst(request: str) -> str:
    """市场分析研究专家"""
    research_agent = Agent(
        system_prompt="您是一位收集和分析市场信息的研究专家。",
        tools=[web_search, calculator]
    )
    return str(research_agent(request))

@tool
def travel_advisor(request: str) -> str:
    """物流和推荐旅行规划专家"""
    travel_agent = Agent(
        system_prompt="您是一位帮助物流、预订和推荐的旅行规划专家。",
        tools=[flight_search, hotel_search, weather_api]
    )
    return str(travel_agent(request))

# 编排器决定何时咨询专家以及如何综合他们的输入
executive_assistant = Agent(
    system_prompt="您与专家协调以提供全面协助。",
    tools=[research_analyst, travel_advisor]
)

编排器模型决定咨询哪些专家以及如何综合他们的输入——不需要预定义的工作流。当您需要清晰的专家边界并希望具有主导代理的委托模式时,这种模式效果很好。

群组:自主协作

群组使代理能够以自组织的方式自主协作,决定何时将任务交给彼此。这适用于创造性协作和涌现性问题解决,其中多个视角增加价值。

考虑一个需要分析新产品机会的市场研究项目。传统方法可能遵循严格的序列:研究→分析→写作。但真正的研究更加混乱——您可能在分析过程中发现需要额外数据,或者在写作时意识到不同的分析框架会更引人注目。

1
2
3
4
5
6
7
8
9
from strands import Agent
from strands.multiagent import Swarm

researcher = Agent(name="researcher", system_prompt="您彻底研究主题...")
analyst = Agent(name="analyst", system_prompt="您分析数据并创造见解...")
writer = Agent(name="writer", system_prompt="您撰写全面报告...")

# 代理通过模型驱动的交接自主协调
market_research_team = Swarm([researcher, analyst, writer])

在群组中,研究人员可能开始收集信息,然后在找到有趣模式时交给分析师。分析师可能发现空白并交回给研究人员以获取更具体的数据。作家可能早期加入对话,根据什么能构成引人入胜的叙述来帮助塑造研究方向。

与代理即工具的关键区别在于共享上下文。在分层系统中,编排器决定在专家之间传递什么信息。在群组中,所有代理都可以访问相同的对话历史,从而实现更流畅的协作和高级指令。您可以告诉群组“研究这个市场机会”,而无需确切指定工作应该如何分配——代理根据他们对不断发展的任务的共享理解来解决问题。

群组以可预测的执行换取涌现能力,使其非常适合复杂的研究任务、头脑风暴场景和最佳方法不明确的创意项目。

图:结构化工作流

图提供确定性工作流,其中执行遵循预定义路径。虽然图中的单个代理使用模型驱动执行,但图结构确保维护特定序列和依赖关系。

这种模式在需要强制检查点或合规要求的业务流程中表现出色。例如,财务分析工作流可能需要研究→风险评估→监管审查→最终建议,每一步都建立在前一步的基础上,某些步骤需要特定批准。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from strands import Agent
from strands.multiagent import GraphBuilder

builder = GraphBuilder()

builder.add_node(researcher, "research")
builder.add_node(analyst, "analysis")
builder.add_node(writer, "report")

builder.add_edge("research", "analysis")
builder.add_edge("analysis", "report")

graph = builder.build()

AWS团队已将图用于某些转换必须按顺序进行的数据管道编排,以及审计跟踪需要特定逐步文档的合规工作流。模型驱动方法仍然适用于每个节点内部——研究代理可以根据发现的内容调整其方法——但整体流程保持可预测。

图的限制在于它们的刚性。如果分析师发现他们需要额外研究,他们不能直接请求——工作流需要完成并可能重新启动。这使得图非常适合充分理解的过程,但不太适合探索性或创造性工作。

元代理:动态编排

元代理是配备工具的单个代理,让它们能够思考思考——它们可以动态创建其他代理、编排工作流并参与递归问题解决。它们代表了模型驱动方法的最终表达:可以构建自身编排技术的代理。

将元代理视为高级架构师,他不仅可以解决问题,还可以决定如何构建问题解决方法。当面临复杂挑战时,它可能推理:“这需要深度研究和创造性综合。我应该创建一个专家群组,然后使用图来确保最终可交付成果符合质量标准。”

1
2
3
4
5
6
7
from strands import Agent
from strands_tools import graph, swarm, use_agent, think, workflow

meta_agent = Agent(
    system_prompt="您可以动态创建专业代理并编排复杂工作流。",
    tools=[graph, swarm, use_agent, think, workflow]
)

元代理在随时间演变的动态系统中表现出色。关键好处是它们的额外动态水平——它们可以创建未预定义的代理,为新兴需求开发新工具,根据变化的条件调整其编排策略,并在了解领域更多信息时发展其问题解决方法。

与其他预先定义代理和工具的模式不同,元代理可以按需生成新专家和创建自定义工具。分析新技术趋势?元代理可能为监管影响、市场动态和技术可行性创建领域专家——这些代理在特定需求出现之前并不存在。它还可能开发专门的数据收集工具、分析框架或针对该特定领域的报告格式。

这种动态代理和工具创建使得系统能够成长和适应,而不是遵循固定模式。

通过评估建立信心

模型驱动方法需要强大的评估,以建立代理按预期执行的信心,特别是当它们对工具使用和任务编排做出自主决策时。

由于模型驱动代理做出动态决策而不是遵循预定路径,评估变得更加重要和细致。您不仅需要评估代理是否得到了正确答案,还需要评估它是否对如何处理问题做出了良好决策。

模型驱动方法改变了我们对评估本身的思考方式。当代理动态调整其行为时,使用静态数据集的传统测试变得不足。这种转变需要与所测试系统智能相匹配的新评估范式。

LLM评判器为大规模评估代理响应提供了强大方法,但必须仔细校准以与最终用户期望保持一致。优先考虑技术准确性的LLM评判器可能错过对实际用户重要的细微差别,如语调、帮助性或实际适用性。

由LLM驱动的模拟用户支持使用不断发展的数据集进行动态测试,创建静态测试用例无法捕获的现实交互模式。然而,这些模拟用户也必须校准以表现得像真实最终用户,而不是理想化的测试场景。目标是真实的用户行为,而不是完美的用户行为。

模型驱动代理的关键评估维度包括:

  • 工具选择适当性——代理是否为任务选择了正确的工具?
  • 推理质量——代理的方法是否合乎逻辑?
  • 适应性——代理处理意外场景的能力如何?
  • 效率——代理是否在没有不必要步骤的情况下完成任务?

模型驱动代理的非确定性性质意味着您需要统计上显著的基线和持续评估来跟踪随时间变化的性能。这种评估投资使您能够自信地部署做出自主决策的代理。

范式转变:从刚性控制到动态适应

模型驱动方法代表了我们对AI代理思考方式的根本转变。我们不再试图通过复杂编排控制代理行为的每个方面,而是提供正确的工具、上下文和目标,然后让模型动态确定最佳方法。

这种转变解决了一个核心问题:预定逻辑难以处理不可预测的世界。当用户以意外方式提问、API返回意外响应或业务需求变化时,传统框架会崩溃。它们失败是因为它们只能处理开发人员预料到并编写代码处理的情况。

模型驱动代理会适应。当API调用失败时,它们会推理替代方案。当用户提出意外问题时,它们会想办法使用可用工具来提供帮助。当需求演变时,它们调整方法而无需更改代码。这种适应性来自利用模型的推理能力,而不是与之对抗。

Strands中采用的方法使代理能够处理不断变化的需求和数据,同时减少开发人员需要管理的复杂性。您可以两者兼得:快速上手的简单性和生产需求时的完全可配置能力。

模型驱动方法不是关于构建更好的编排框架。它是关于认识到现代LLM已经发展到不再需要如此刚性指导。通过利用模型的推理能力进行编排,我们可以构建既更有能力又更易于开发的代理。这一理念是Strands中一切构建的基础。前往Strands Agents网站立即试用。

寻找更多开源内容?请务必在LinkedIn上关注AWS开源!

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计