在当前的 AI 开发领域,构建能够与外部系统交互、处理复杂工作流并维护上下文对话的智能体(Agent)已成为新的前沿。然而,许多现有框架要求开发者定义复杂的“链”或固定的工作流,这在一定程度上限制了 Agent 的灵活性。

Strands 是一个开源的 Python SDK,它为此提供了一种新的思路:模型驱动(model-driven) 。其核心理念是,与其为 Agent 硬编码一套复杂的执行逻辑,不如充分利用现代大语言模型(LLM)强大的原生推理和规划能力。开发者只需为 Agent 提供一个模型(大脑)、一套工具(双手)和一个提示(任务),剩下的规划、推理和工具调用过程则交由模型自主完成。

接下来一起探讨一下 Strands 框架的技术细节,从其核心架构、工作原理到具体的代码实现,为你展示如何利用这个框架来加速 AI Agent 的开发与部署。

核心架构 ️

一个 Strands Agent 由三个基本组件构成:

  1. 模型 (The Model) :作为 Agent 的“大脑”,负责推理和决策。Strands 的设计是模型无关的,支持多种模型提供方,给予了开发者极大的灵活性 :

    1. Amazon Bedrock:可访问多种业界领先的基础模型。
    2. Anthropic API:直接使用 Claude 系列模型。
    3. Llama API:支持 Meta 的 Llama 系列模型。
    4. Ollama:允许在本地运行开源模型,非常适合开发和调试。
    5. OpenAI:通过 LiteLLM 接入。
    6. 自定义 Provider:开发者也可以接入自己的模型服务。
  2. 工具 (The Tools) :这些是 Agent 用来与外部世界交互并执行具体操作的能力。任何 Python 函数都可以通过一个简单的装饰器 @tool 变成 Agent 可用的工具。此外,Agent 也可以使用遵循模型上下文协议(Model Context Protocol, MCP)的工具服务器。

  3. 提示 (The Prompt) :这是用自然语言下达给 Agent 的指令,定义了它需要完成的任务。通常包括用于设定其角色和行为准则的系统提示,以及用户输入的具体任务用户提示

这三个组件协同工作的机制被称为“智能循环”(Agentic Loop)。

智能循环 (Agentic Loop)

“智能循环”是 Strands 框架的核心运行机制。它并非一套预设的规则,而是一个利用 LLM 自身能力进行动态决策的迭代过程 :

  1. 分析上下文:Strands 将当前的用户提示、完整的对话历史以及所有可用工具的描述打包。
  2. 调用 LLM:将打包好的上下文发送给选定的 LLM,请求其规划下一步行动。
  3. 模型决策:LLM 基于上下文进行推理,并决定是直接回答、向用户提问,还是选择一个或多个工具来执行。
  4. 执行与反馈:如果 LLM 决定调用工具,Strands 会执行相应的函数,并将返回结果(成功的数据或错误信息)添加回对话历史中。
  5. 循环:这个过程会不断重复,直到 LLM 判断任务已经完成,并给出最终的答案。

上手实践:构建你的第一个 Agent ️

我通过一个完整的例子来展示如何安装 Strands 并构建一个具备多种工具的 Agent。

登录亚马逊云科技账号

要用亚马逊云科技的服务,首先得有一个账号,这很合理吧~

说起亚马逊云科技的服务就不得不提最近的一个免费套餐升级——Free Tier 2.0

相比起之前的免费套餐,这次升级了以下内容:

需要注意的是,该套餐不支持北京与宁夏区域使用。

环境设置

首先,你需要一个 Python 3.10 或更高版本的环境。然后,创建并激活一个虚拟环境 :

# 创建虚拟环境
python -m venv.venv

# 激活虚拟环境 (Linux/macOS)
source.venv/bin/activate

# 激活虚拟环境 (Windows)
#.venvScriptsactivate.bat

接下来,安装 Strands 核心库、官方工具集和构建工具 :

pip install strands-agents strands-agents-tools strands-agents-builder

编写 Agent 代码

创建一个 Python 文件(例如 my_agent.py),我们将在这里定义一个自定义工具,并将其与一些内置工具一起提供给 Agent。

下面的代码示例创建了一个可以模拟掷骰子的自定义工具 roll_dice,并结合了内置的计算器、当前时间查询和 Python 代码执行器工具。

from strands import Agent, tool
import random
from strands_tools import calculator, current_time, python_repl

# 1. 使用 @tool 装饰器定义一个自定义工具
@tool
def roll_dice(sides: int):
    """
    模拟一个指定面数的骰子。
    文档字符串 (docstring) 对 LLM 理解工具功能至关重要。

    Args:
        sides: 骰子的面数。
        
    Returns:
        一个介于 1 和指定面数之间的随机整数。
    """
    return random.randint(1, sides)

# 2. 创建 Agent 实例,并通过列表传入所有可用工具
agent = Agent(
    tools=[calculator, current_time, python_repl, roll_dice]
)

# 3. 定义一个需要多种工具协作完成的复杂任务
message = """
我有4个请求:
1. 现在是什么时间?
2. 计算 3111696 / 74088 的结果。
3. 掷一个20面的骰子。
4. 输出一个 Python 脚本来完成我们刚刚讨论的所有事情!
   在输出脚本之前,请使用你的 Python 工具来确认脚本可以正常工作。
"""

# 4. 将任务交给 Agent 执行
agent(message)

在这个例子中,@tool 装饰器自动将 roll_dice 函数转换为 LLM 可以理解和调用的格式。函数签名中的类型提示(sides: int)和详细的文档字符串对于帮助 LLM 准确地使用该工具至关重要。

运行此脚本 (python my_agent.py),你将看到 Agent 会依次调用 current_timecalculatorroll_dicepython_repl 工具来完成所有请求,并最终生成一个可执行的脚本。

模型配置与切换 ️

Strands 默认会尝试使用 Amazon Bedrock 上的 Claude 3.7 Sonnet 模型。但你可以轻松地将其配置为使用其他模型。

Amazon Bedrock (默认)

如果你想明确指定模型 ID 或区域,可以这样做 :

from strands import Agent
from strands.models import BedrockModel

# 配置 Bedrock 模型
bedrock_model = BedrockModel(
    model_id="anthropic.claude-3-sonnet-20240229-v1:0", # 示例模型 ID
    region_name='us-west-2',
    temperature=0.3,
)
agent = Agent(model=bedrock_model)

Anthropic Claude (通过 API)

首先需要安装相应的依赖:pip install 'strands-agents[anthropic]'

from strands.models import AnthropicModel

anthropic_model = AnthropicModel(
    client_args={
        "api_key": "<YOUR_ANTHROPIC_API_KEY>",
    },
    max_tokens=1024,
    model_id="claude-3-opus-20240229", # 示例模型 ID
    params={
        "temperature": 0.7,
    }
)
# agent = Agent(model=anthropic_model)

Ollama (本地模型)

对于本地开发,使用 Ollama 非常方便。首先安装依赖:pip install 'strands-agents[ollama]'

from strands.models import OllamaModel

ollama_model = OllamaModel(
    host="http://localhost:11434",
    model_id="llama3" # 确保你本地已拉取该模型
)
# agent = Agent(model=ollama_model)

调试与日志

在开发过程中,理解 Agent 的内部决策过程至关重要。Strands 内置了对日志记录的支持,可以轻松开启详细的调试信息。

import logging
from strands import Agent

# 激活 Strands 的 DEBUG 级别日志
logging.getLogger("strands").setLevel(logging.DEBUG)
logging.basicConfig(
    format="%(levelname)s | %(name)s | %(message)s",
    handlers=
)

agent = Agent
agent("Hello!")

运行以上代码,你将在控制台看到 Agent 循环的每一步,包括模型输入、工具选择、工具调用和返回结果等详细信息,这对于调试和优化 Agent 的行为非常有帮助。

以上就是本文的全部内容啦。最后提醒一下各位工友,如果后续不再使用相关服务,别忘了在控制台关闭,避免超出免费额度产生费用~

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]