title: “使用 Strands 构建 Agents” weight: 200
在本模块中,我们将使用 Strands Agents SDK 为一个名为 AnyCompany Shop 的虚构在线零售商店构建并部署一个 AI 驱动的客户服务 Agent。该 agent 与运行在我们集群中的 Qwen2.5-3B 模型进行交互,帮助客户处理订单、产品问题和退货。
一个 agent,在每个模块中不断演进。
| 模块 | Agent 如何受益 |
|---|---|
| Strands(本模块) | 核心循环 - 接收查询、推理、响应 |
| Langfuse | 追踪每一次 LLM 调用和工具调用,以调试缓慢或错误的响应 |
| Milvus | 将产品目录 + FAQ 存储为嵌入向量,用于 RAG 驱动的产品答复 |
| MCP | 让 agent 能够访问工具:查询订单、检查库存、发起退货 |
| A2A | 拆分为协同工作的专家 agent |
我们从简单开始:一个由 LLM 驱动、带有一个工具的对话循环。每个模块都会叠加一个新能力。

lookup_order一个用于构建 agent 的开源 Python SDK。由 LLM 决定调用哪些工具以及调用的顺序。关键概念:
@tool 装饰的 Python 函数,agent 可以调用它们完整源代码位于 ~/environment/modules/20-self-managed/200-strands-agents/customer-agent。
cd ~/environment/modules/20-self-managed/200-strands-agents/customer-agent
该项目由六个文件组成:agent.py、tools.py、server.py、Dockerfile、requirements.txt 和 k8s.yaml。前两个是核心教学文件。它们包含 agent 逻辑和工具定义。其余文件是基础设施:server.py 是一个精简的 FastAPI 封装,通过 HTTP 将 agent 暴露给聊天 UI,Dockerfile 和 requirements.txt 处理容器化和依赖项,k8s.yaml 定义 Kubernetes 部署。
model = OpenAIModel(
client_args={
"base_url": litellm_base_url,
"api_key": os.environ.get("LITELLM_API_KEY", "not-needed"),
},
model_id="qwen2-5-3b-neuron",
params={"max_tokens": 1024, "temperature": 0.3},
)
model_id="qwen2-5-3b-neuron":LiteLLM 将其解析为 vLLM Service。切换到 "nova-lite",我们就能在 Bedrock 上运行,无需任何其他代码更改extra_body.chat_template_kwargs.enable_thinking = false),因此 agent 无需处理它LITELLM_BASE_URL 来自 Terraform 预置的 agent-config ConfigMap
@tool
def lookup_order(order_id: str) -> dict:
"""Look up an order by its order ID and return the order details.
Args:
order_id: The order ID to look up (e.g., ORD-12345)
Returns:
A dictionary containing order details including items, status, tracking number,
and estimated delivery date. Returns an error message if the order is not found.
"""
Strands 根据类型提示和 docstring 构建工具 schema。LLM 会读取所有这些内容来决定何时调用工具。编写 docstring 时要像 LLM 会阅读它们一样,因为它确实会。
模拟的 ORDERS 字典将在 Agent Tool Access (MCP) 实验中被真实的 MCP server 替换。
我们已经为 customer-agent 创建了 Amazon ECR 仓库。一次性构建并推送:
cd ~/environment/modules/20-self-managed/200-strands-agents/customer-agent
IMG=$ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/customer-agent:strands
docker build --push -t $IMG .
:strands 是特定于模块的标签。每个实验使用不同的标签名称,因此 kubectl describe pod 会准确告诉我们正在运行哪个模块的代码,而一次全新的 kubectl apply 就足以滚动 Deployment(spec 已更改,无需 rollout restart)。
这是唯一一个我们手动构建并推送镜像的实验,因此我们可以看到完整的 源代码 → 容器镜像 → ECR → EKS 循环的端到端过程。对于之后的每个实验,我们都已预先构建并将镜像推送到 ECR,因此我们可以直接部署。任何时候想发布我们自己的更改,都可以重新构建并推送。
k8s.yaml 是一个 Deployment + 在 8080 端口上的 ClusterIP Service。envFrom 挂载 agent-config ConfigMap,因此 LITELLM_BASE_URL 会自动到位。
envsubst < k8s.yaml | kubectl apply -f -
kubectl rollout status deployment/customer-agent --timeout=120s
打开聊天 UI 标签页(来自 Sample Application 步骤)。从配置列表中选择 Customer Agent (Self-managed GenAI),然后尝试:
Hi, I ordered a laptop last week and it still hasn't arrived. My order ID is ORD-12345. Can you help?
I want to return the headphones I bought. Order ORD-11111.
Can you check on order ORD-99999?
最后一个测试了"订单不存在"的路径,优秀的 agent 会优雅地处理失败。

lookup_order 工具接下来:可观测性,追踪每一次 LLM 调用和工具调用。