🔥 20 行代码搞定 AI Agent!查天气、算数学、读文档全包了

25 阅读6分钟

别再扉写 if-else 判断该调哪个 API 了。让模型自己选。

故事的开始

"老板让我两天做个能调 API 的 AI Agent。"

周一早上开完会,我整个人是懵的。Agent 这东西我知道,但从零搭一个?两天?

然后同事甩给我一个链接——Strands Agents SDK。

我花了 20 分钟跑通了第一个 demo。花了半天写完了天气查询 + 数学计算 + 文档检索。还剩一天多的时间我用来摸鱼……哦不,用来写这篇教程。

先看效果

Agent 跑起来后,你可以这样问:

"北京今天天气怎么样?帮我算 2 的 10 次方。再查一下 Amazon S3 是什么。"

它会自己拆任务、调工具、汇总结果。你不用写一行调度逻辑。

代码?一共就这些:

from strands import Agent, tool
from strands_tools import calculator
import urllib.request, json

@tool
def get_weather(city: str) -> str:
    """查询指定城市的当前天气信息。

    Args:
        city: 城市名称,如 Beijing、Shanghai
    """
    url = f"https://wttr.in/{city}?format=j1"
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
    with urllib.request.urlopen(req, timeout=10) as resp:
        data = json.loads(resp.read().decode())
    current = data["current_condition"][0]
    return f"{city}: {current['temp_C']}°C, {current['weatherDesc'][0]['value']}"

@tool
def search_docs(keyword: str) -> str:
    """在技术文档中搜索关键词。

    Args:
        keyword: 要搜索的关键词
    """
    docs = {
        "bedrock": "Amazon Bedrock 是亚马逊云科技的全托管生成式 AI 服务。",
        "lambda": "AWS Lambda 是事件驱动的无服务器计算服务。",
        "s3": "Amazon S3 是对象存储服务,支持无限存储。"
    }
    for key, value in docs.items():
        if keyword.lower() in key:
            return value
    return f"未找到关于 '{keyword}' 的文档。"

agent = Agent(tools=[calculator, get_weather, search_docs])
agent("北京天气如何?2 的 10 次方等于多少?什么是 S3?")

没有路由逻辑。没有意图识别。模型自己决定调哪个工具。

这到底是怎么回事

Strands Agents 是亚马逊云科技开源的 AI Agent SDK。

核心理念叫 model-driven orchestration,翻译过来就是:模型驱动编排。

说白了:

  1. 你注册一堆工具(Python 函数)
  2. 用户提问
  3. 模型自己看问题,决定调哪个工具
  4. 调完拿结果,继续推理
  5. 重复 3-4 直到任务完成

你要做的就是:写工具函数 + 把它们注册到 Agent。其他的,模型搞定。

环境搭建(5 分钟)

装包

python -m venv .venv
source .venv/bin/activate
pip install strands-agents strands-agents-tools

配凭证

默认用 Amazon Bedrock,所以需要亮马逊云科技凭证:

aws configure
# 或者
export AWS_ACCESS_KEY_ID=你的AK
export AWS_SECRET_ACCESS_KEY=你的SK
export AWS_DEFAULT_REGION=us-west-2

然后去 Amazon Bedrock 控制台开通 Claude 4 Sonnet 模型权限(us-west-2 区域)。

⚠️ 坑:我第一次用了 ap-northeast-1,结果报 AccessDeniedException。Claude 4 Sonnet 不是所有区域都能用,us-west-2 准没错。

@tool 装饰器详解

这是 Strands Agents 的杀手级特性。一个装饰器把普通函数变成 Agent 可调用的工具。

from strands import tool

@tool
def get_weather(city: str) -> str:
    """查询指定城市的当前天气信息。

    Args:
        city: 城市名称,如 Beijing、Shanghai、Tokyo
    """
    import urllib.request, json
    url = f"https://wttr.in/{city}?format=j1"
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
    with urllib.request.urlopen(req, timeout=10) as resp:
        data = json.loads(resp.read().decode())
    current = data["current_condition"][0]
    temp = current["temp_C"]
    desc = current["weatherDesc"][0]["value"]
    humidity = current["humidity"]
    return f"{city}: {temp}°C, {desc}, 湿度 {humidity}%"

三个要点:

  1. docstring 是灵魂。模型靠它理解这个工具干嘛。写得越清楚,调用越准
  2. 类型注解必须有。SDK 用它生成 JSON Schema,模型根据 Schema 填参数
  3. 返回字符串。模型好理解

踩坑:一开始我 docstring 只写了一句"查天气"。结果模型经常不调这个工具。改成详细描述 + 参数说明后,命中率飙升。

接 MCP Server:读 AWS 官方文档

MCP(Model Context Protocol)是一个开放协议。可以让 Agent 连接外部工具服务器。

Strands Agents 内置支持。用 aws-documentation-mcp-server 能让 Agent 实时检索 AWS 文档。

from strands import Agent
from strands.tools.mcp import MCPClient
from mcp import stdio_client, StdioServerParameters

aws_docs_client = MCPClient(
    lambda: stdio_client(
        StdioServerParameters(
            command="uvx",
            args=["awslabs.aws-documentation-mcp-server@latest"]
        )
    )
)

with aws_docs_client:
    agent = Agent(tools=aws_docs_client.list_tools_sync())
    response = agent("Amazon Bedrock 用 Python 怎么调用?")
    print(response)

坑:uvx: command not found。需要先装 uv

pip install uv

自定义工具 + MCP 混合用

from strands import Agent, tool
from strands.tools.mcp import MCPClient
from mcp import stdio_client, StdioServerParameters
from strands_tools import calculator

@tool
def get_weather(city: str) -> str:
    """查询指定城市的当前天气信息。

    Args:
        city: 城市名称
    """
    import urllib.request, json
    url = f"https://wttr.in/{city}?format=j1"
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
    with urllib.request.urlopen(req, timeout=10) as resp:
        data = json.loads(resp.read().decode())
    current = data["current_condition"][0]
    return f"{city}: {current['temp_C']}°C, {current['weatherDesc'][0]['value']}"

aws_docs_client = MCPClient(
    lambda: stdio_client(
        StdioServerParameters(
            command="uvx",
            args=["awslabs.aws-documentation-mcp-server@latest"]
        )
    )
)

with aws_docs_client:
    all_tools = [calculator, get_weather] + aws_docs_client.list_tools_sync()
    agent = Agent(tools=all_tools)
    agent("上海天气怎么样?帮我查查 S3 的 Python 用法。再算 99 * 99。")

Agent 自己分辨哪些问题用哪个工具。混着来也不慌。

多 Agent 协作

一个 Agent 能力有限?搞多个,让它们分工。

思路:把子 Agent 包装成 tool,注册给主 Agent。

from strands import Agent, tool
from strands_tools import calculator

@tool
def get_weather(city: str) -> str:
    """查询城市天气。"""
    import urllib.request, json
    url = f"https://wttr.in/{city}?format=j1"
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
    with urllib.request.urlopen(req, timeout=10) as resp:
        data = json.loads(resp.read().decode())
    current = data["current_condition"][0]
    return f"{city}: {current['temp_C']}°C, {current['weatherDesc'][0]['value']}"

# 子 Agent:天气专家
weather_agent = Agent(
    system_prompt="你是天气查询助手,用 get_weather 工具回答天气问题。",
    tools=[get_weather]
)

# 子 Agent:数学专家
math_agent = Agent(
    system_prompt="你是数学计算助手,用 calculator 工具解决数学问题。",
    tools=[calculator]
)

@tool
def ask_weather_expert(question: str) -> str:
    """向天气专家提问,查询天气信息时使用。

    Args:
        question: 关于天气的问题
    """
    return str(weather_agent(question))

@tool
def ask_math_expert(question: str) -> str:
    """向数学专家提问,需要数学计算时使用。

    Args:
        question: 数学问题
    """
    return str(math_agent(question))

# 主 Agent:协调者
coordinator = Agent(
    system_prompt="你是智能助手。天气问题交给天气专家,数学问题交给数学专家。",
    tools=[ask_weather_expert, ask_math_expert]
)

coordinator("北京今天多少度?123 × 456 等于多少?")

每个 Agent 专注自己的事,主 Agent 只管分活。

换模型

默认 Claude 4 Sonnet。想用别的:

from strands import Agent
from strands.models import BedrockModel

model = BedrockModel(
    model_id="us.amazon.nova-pro-v1:0",
    temperature=0.3,
    streaming=True
)

agent = Agent(model=model, tools=[...])

Amazon Bedrock 上有多种模型可选,Claude 系列和 Amazon Nova 系列都支持。

踩坑合集

问题原因解法
ImportError: cannot import name 'tool'SDK 版本太老pip install --upgrade strands-agents
工具不被调用docstring 太简略写详细的功能描述和参数说明
MCP 服务器超时首次下载依赖慢等一会,第二次就快了
AccessDeniedException区域不对或没开通去 Bedrock 控制台开通模型权限
uvx: command not found没装 uvpip install uv

写在后面

从零到一个能查天气、算数学、读文档的 AI Agent,我花了不到一个小时。

这个 SDK 的哲学很简单:你写函数,模型做决策。

代码已经全放上面了。试试呗。


链接: