问题与目标
理解循环和工具后,需要先完成一个单 Agent 基线,再进入 LangGraph 和多 Agent。单 Agent 更容易观察模型怎样选工具、怎样使用观察结果,以及失败发生在模型、工具还是验收层。
本篇实现一个只读巡检助手:模型可以查询设备和规则,但不能创建工单。输入是自然语言目标,输出包含最终回答和完整消息轨迹。写操作、记忆和人工审批留到后续文章。
核心概念
LangChain create_agent 在内部运行模型—工具循环:模型不再请求工具时结束。工具可以连续或并行调用,Agent 状态至少包含消息历史。
单 Agent 的边界应保持清楚:
- 工具数量少且职责不重叠;
- 系统提示说明事实来源和禁止行为;
- 工具仍独立完成权限校验;
- 有最大步数、超时和最终输出检查;
- 轨迹可以回放,但日志不保存密钥和敏感原文。
可运行实现
bash
python -m pip install "langchain>=1,<2" "langchain-openai>=1,<2"
export OPENAI_API_KEY="replace-with-your-key"
export AGENT_MODEL="provider-model-name"
python
import os
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def get_device_status(device_id: str) -> dict:
"""查询 AX 系列设备当前状态,只读。"""
data = {"AX-3": {"online": False, "temperature": 38.2}}
return data.get(device_id, {"error": "not_found"})
@tool
def get_inspection_rule(topic: str) -> dict:
"""查询巡检规则,只返回与 topic 相关的规则。"""
rules = {"offline": "设备离线时通知值班人员检查网络,不自动创建工单。"}
return {"rule": rules.get(topic, "现有规则无法确认")}
agent = create_agent(
model=os.environ["AGENT_MODEL"],
tools=[get_device_status, get_inspection_rule],
system_prompt=(
"你是只读巡检助手。先查询事实,再查询必要规则;"
"不得声称已经创建工单,不得补充工具结果之外的设备事实。"
),
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "检查 AX-3 是否需要人工处理,并说明依据。"}]},
config={"recursion_limit": 6, "tags": ["stage08", "single-agent"]},
)
print(result["messages"][-1].text)
for message in result["messages"]:
print(type(message).__name__, getattr(message, "tool_calls", None))
不同模型对工具调用与 .text 支持存在差异,应以当前集成文档为准。验收时不仅查看最终文字,还要确认是否调用了状态工具、是否在离线时查询了规则,以及有没有虚构写操作。
常见问题与排查
Agent 不调用工具直接回答
检查工具名称、描述和系统规则是否清晰,再加入必须查询实时事实的测试样本。不要用“你一定要调用”掩盖工具职责重叠。
Agent 在两个工具之间循环
检查工具结果是否明确表示成功、缺失或错误;设置 recursion_limit,并记录重复的工具名与参数。必要时改成确定性 Workflow。
工具异常导致整次调用失败
对可预期异常返回结构化错误,或使用 Tool Middleware 分类处理。认证与权限失败不能被包装成可重试提示。
最终回答与轨迹不一致
增加结果校验:答案引用的设备、状态和操作必须能在本轮 ToolMessage 中找到。高风险结论进入人工复核。
小结
单 Agent 基线证明了模型能够根据目标选择只读工具并整理结果,同时让工具轨迹与失败边界保持可见。复杂状态、恢复和审批不应继续堆在这个循环里,下一步使用 LangGraph 显式管理流程。
许可协议:CC BY-NC 4.0
更新于 1 小时前
觉得文章有帮助?点个赞吧!
0 条评论


