把一个"让 AI 帮我查资料、整理摘要"的想法落地,听起来简单——调几个 API、拼几段 prompt 就行。但真正动手时你会发现:多轮对话的状态管理、工具调用的编排、错误重试、上下文窗口控制……每一项都能把一个周末项目拖成几个月的工程。Strands 的思路是:把这些重复的基建工作收进框架层,让开发者把精力放在"我的助手要做什么"而不是"怎么把 API 串起来"。
为什么搭一个研究助手这么费劲
一个能用的研究助手至少要完成这几步:
- 理解用户意图——用户说"帮我调研 Rust 在嵌入式领域的应用",助手需要拆解成多个子问题。
- 调用外部工具——搜索网页、读取 PDF、查询数据库,每个工具的输入输出格式不同。
- 汇总与推理——把多源信息交叉比对,去重、排序、生成结构化摘要。
- 多轮交互——用户追问时,助手要记住之前的上下文,而不是从头开始。
手动编排这些步骤,你很快就会写出这样的代码:一个巨大的 if-elif 链处理工具路由,一个手动维护的 conversation_history 列表,一个到处 try-except 的重试逻辑。Strands 把这些模式抽象成了 Agent + Tool 的声明式组合。
Strands 的核心模型:Agent、Tool、Model
Strands 的设计围绕三个概念:
- Agent:自治单元,接收用户指令,自主规划执行步骤,调用工具,返回结果。
- Tool:Agent 可调用的能力单元——一个 Python 函数,加上描述签名,Agent 就知道什么时候该用它、怎么传参。
- Model:底层大模型驱动推理,你可以切换不同提供商。
关键区别在于:Strands 采用 模型驱动的编排(model-driven orchestration)。你不需要写流程图或状态机来规定"先搜索再摘要再输出"——Agent 自己决定调用顺序。你只需要告诉它有哪些工具可用。
动手搭一个研究助手
下面是一个可以直接运行的最小研究助手,使用 Strands Agents SDK。它能搜索网页、读取本地文件、把研究结果写入 Markdown。
前置条件:Python 3.10+,安装依赖
pip install strands-agents strands-tools,并配置好模型提供商的 API Key(示例使用 OpenAI 兼容接口,也可替换为其他支持的模型)。
# research_assistant.py
from strands import Agent
from strands.tools import http_request, file_read, file_write, editor
# 定义研究助手的系统提示——这决定了它的行为边界
SYSTEM_PROMPT = """你是一个专业研究助手。你的工作流程:
1. 收到研究主题后,先拆解成 2-4 个关键子问题。
2. 对每个子问题,使用 http_request 工具搜索相关信息。
- 构造精准的搜索 URL,优先使用权威来源。
3. 如果用户提供了本地参考文件,使用 file_read 读取补充。
4. 综合所有来源,生成结构化研究报告,包含:
- 摘要(200 字以内)
- 各子问题的分析(附来源标注)
- 结论与建议
5. 使用 file_write 将报告保存为 Markdown 文件。
规则:
- 不确定的信息标注"待验证",不编造数据。
- 每个论点至少关联一个来源。
- 如果搜索结果不足,明确告知用户而非强行补全。
"""
# 创建 Agent——声明可用工具,框架负责编排
agent = Agent(
model="openai:gpt-4o", # 模型驱动推理,可替换为其他支持的模型
tools=[http_request, file_read, file_write, editor],
system_prompt=SYSTEM_PROMPT,
)
# 运行研究任务
topic = "Rust 语言在嵌入式开发中的应用现状与趋势,包括主要框架、社区生态和厂商采纳情况"
result = agent(topic)
# 打印结果
print(result.message)
运行方式:
# 设置模型 API Key(示例使用 OpenAI,按实际提供商调整)
export OPENAI_API_KEY="sk-..."
# 运行助手
python research_assistant.py
Agent 会自主完成:拆解子问题 → 构造搜索 URL → 调用 http_request → 读取返回内容 → 综合推理 → 调用 file_write 保存报告。整个链条你没有写任何流程控制代码。
自定义工具:让助手访问你的内部数据
Strands 的 Tool 就是带描述签名的 Python 函数。如果你的研究助手需要查询内部知识库,加一个自定义工具即可:
# custom_tools.py
from strands.tools import tool
@tool(description="查询公司内部技术wiki。输入:搜索关键词。输出:匹配的文档标题和摘要列表。")
def query_internal_wiki(keyword: str) -> str:
"""模拟内部知识库查询——实际项目中替换为真实 API 调用"""
# 示例:调用内部搜索服务
import requests
resp = requests.get(
f"https://wiki.internal.example.com/api/search",
params={"q": keyword, "limit": 5},
headers={"Authorization": f"Bearer {WIKI_TOKEN}"},
timeout=10,
)
if resp.status_code != 200:
return f"查询失败,状态码:{resp.status_code}"
results = resp.json().get("documents", [])
if not results:
return "未找到相关内部文档。"
# 格式化为 Agent 可理解的文本
formatted = []
for doc in results:
formatted.append(f"- **{doc['title']}**:{doc['summary']}")
return "\n".join(formatted)
# 把自定义工具加入 Agent
agent = Agent(
model="openai:gpt-4o",
tools=[http_request, file_read, file_write, query_internal_wiki],
system_prompt=SYSTEM_PROMPT,
)
@tool 装饰器做了两件事:把函数注册为 Agent 可调用的工具,同时把 description 和函数签名(参数名、类型)暴露给模型。Agent 在推理时根据描述决定是否调用,根据签名构造参数——你不需要写路由逻辑。
多轮对话与上下文管理
研究任务很少一轮就结束。用户可能追问"重点对比 RTOS 和裸机方案的性能数据",助手需要记住之前的研究结果。Strands 的 Agent 内置了对话历史管理:
# 多轮研究对话示例
from strands import Agent
agent = Agent(
model="openai:gpt-4o",
tools=[http_request, file_read, file_write],
system_prompt=SYSTEM_PROMPT,
)
# 第一轮:初始研究
response1 = agent("调研 WebAssembly 在边缘计算中的使用案例")
print(f"第一轮结果:{response1.message}\n")
# 第二轮:追问——Agent 自动携带上文
response2 = agent("重点分析 WasmEdge 和 Wasmer 在 IoT 场景的性能对比数据")
print(f"第二轮结果:{response2.message}\n")
# 第三轮:要求输出格式调整
response3 = agent("把之前的分析整理成表格形式,保存为 comparison.md")
print(f"第三轮结果:{response3.message}")
每轮调用 agent(...) 时,Strands 自动维护对话历史和工具调用记录。模型能看到完整的上下文链路,包括之前调用了哪些工具、返回了什么数据。你不需要手动拼接 messages 列表。
上线前需要考虑的几件事
成本与延迟控制。 自治 Agent 的工具调用次数不可预测——一个复杂研究任务可能触发 10+ 次搜索。设置合理的超时和最大迭代次数:
agent = Agent(
model="openai:gpt-4o",
tools=[...],
system_prompt=SYSTEM_PROMPT,
max_iterations=15, # 防止无限循环
)
工具权限边界。 file_write 能写任意路径、http_request 能访问任意 URL。生产环境中应该限制工具的访问范围——比如在自定义工具函数内做路径白名单校验、URL 前缀过滤。
模型选择的影响。 推理能力强的模型(GPT-4o、Claude 3.5)编排更准确,但成本高;小模型速度快但容易误选工具或漏掉步骤。研究助手这类多步骤任务,建议用强模型驱动编排,关键摘要生成环节不可省。
输出质量验证。 Agent 生成的报告可能包含事实错误或幻觉。在系统提示中强调"不确定就标注"只是软约束;更可靠的做法是在流程末端加一个校验工具,交叉比对关键数据点。
从想法到产品的路径
Strands 解决的是"编排基建"问题——让你不再手写状态机和工具路由。但一个真正可用的研究助手,还需要在这些方面持续投入:
| 阶段 | 重点 | Strands 提供的支撑 |
|---|---|---|
| 原型验证 | 快速跑通搜索→摘要→输出链路 | Agent + 内置工具,几行代码启动 |
| 工具扩展 | 接入内部数据库、API、文档源 | @tool 装饰器,一个函数即一个工具 |
| 质量保障 | 控制幻觉、限制调用次数、校验输出 | max_iterations、系统提示约束、自定义校验工具 |
| 生产部署 | 监控成本、日志追踪、权限隔离 | 框架层回调钩子、可替换模型提供商 |
从原型到生产不是一步到位的。建议先用内置工具跑通最小流程,确认 Agent 的自主编排符合预期,再逐步替换为自定义工具和更严格的约束。Strands 的声明式风格让每一步增量改动都很小——加一个工具就是加一个函数,改一个行为就是改一段系统提示,不需要重构整个流程。