🤖 从零开始构建智能Agent:物流查询助手完整实战:
手把手教你用LangChain + 通义千问打造一个可用的AI Agent
代码地址:https://github.com/Brian170915/logistic_agent_v1
📋 目录
1️⃣ 项目环境配置:一切从依赖开始
在构建一个功能完备的智能Agent之前,首先需要搭建一个稳定的Python运行环境。本次项目主要依赖langchain、langgraph以及openai等核心库,它们共同构成了Agent的“骨架”与“大脑”。
📄 requirements.txt
# === 核心框架 ===
langchain==1.2.15 # LCEL表达式、链式调用、工具集成
langchain-core==1.3.0 # 基础抽象与运行时
langchain-openai==1.1.16 # OpenAI模型适配器(支持GPT-4o等)
langgraph==1.1.9 # 图结构Agent流程控制
langgraph-checkpoint==4.0.2 # 状态持久化与记忆管理
# === LLM 客户端 ===
openai==2.32.0 # 官方异步/同步客户端
httpx==0.28.1 # 高性能HTTP传输层
tiktoken==0.12.0 # 计算token数量(上下文管理)
# === 数据验证与序列化 ===
pydantic==2.13.3 # 结构化配置与输出解析
pydantic_core==2.46.3
orjson==3.11.8 # 快速JSON处理
ormsgpack==1.12.2 # 消息打包格式
# === 工具与辅助 ===
python-dotenv==1.2.2 # 管理OpenAI API Key
tenacity==9.1.4 # 自动重试机制(应对限流)
tqdm==4.67.3 # 进度条显示
PyYAML==6.0.3 # 读取配置文件
requests==2.33.1 # 原生HTTP请求兜底
🔧 环境安装命令
建议使用Python 3.10+ 创建虚拟环境:
pip install -r requirements.txt
2️⃣ 模型配置:接入通义千问(DashScope)
在构建Agent之前,我们需要配置大语言模型(LLM)的接入信息。本次项目采用阿里云的通义千问(qwen-flash) 作为底层模型,通过兼容OpenAI API的方式与langchain-openai无缝对接。
📄 环境变量文件(.env)
# DashScope API 配置
DASHSCOPE_API_KEY=your-api-key-here # 从阿里云控制台获取
BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
LLM_MODEL=qwen-flash # 快速响应版,性价比高
🔌 在代码中加载配置
使用python-dotenv加载环境变量,并初始化兼容OpenAI接口的ChatModel:
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
# 加载 .env 文件
load_dotenv()
# 读取配置
api_key = os.getenv("DASHSCOPE_API_KEY")
base_url = os.getenv("BASE_URL")
model_name = os.getenv("LLM_MODEL")
# 初始化通义千问模型(兼容OpenAI SDK)
llm = ChatOpenAI(
api_key=api_key,
base_url=base_url,
model=model_name,
temperature=0.7, # 控制随机性,0~2之间
max_tokens=2048, # 最大输出长度
timeout=60, # 请求超时时间(秒)
max_retries=2, # 自动重试次数
)
✅ 测试连通性
建议先发送一条简单消息验证配置是否正确:
from langchain_core.messages import HumanMessage
response = llm.invoke([HumanMessage(content="你好,请介绍一下你自己")])
print(response.content)
预期输出示例:
你好!我是通义千问,阿里云开发的AI助手。我可以回答问题、编写代码、进行文本分析等。有什么我可以帮助你的吗?
💡 小提示
qwen-flash响应速度快、成本低,适合Agent高频调用;若需更强推理能力可换为qwen-maxBASE_URL末尾的/v1必须保留,因为langchain-openai会自动追加/chat/completions路径- API Key 请妥善保管,勿提交到公开代码仓库
3️⃣ 工具定义:为Agent赋予“行动能力”
Agent的核心能力之一就是使用工具。在LangChain中,我们可以通过@tool装饰器快速将一个普通函数包装成符合Agent调用规范的工具。下面以物流单号查询为例,展示如何定义工具并集成到Agent中。
📦 定义物流查询工具(tools/logistics_tools.py)
from langchain.tools import tool
# 定义物流查询工具
@tool
def query_logistics(order_id: str) -> str:
"""
物流单号查询工具
输入参数:物流单号
功能:查询物流的实时位置、运输状态
:param order_id: 物流单号
:return: 物流状态描述
"""
# 模拟物流数据(无真实API,零配置!后期可替换为真实接口)
mock_logistics_data = {
"SF123456": "【顺丰速运】已揽收|广州市天河区→北京市朝阳区|预计1天送达",
"YT789012": "【圆通快递】运输中|已离开上海分拨中心|前往深圳途中",
"JD345678": "【京东物流】派送中|快递员:李师傅|电话:138****1234",
"ZT901234": "【中通快递】已签收|签收人:门卫|2025-12-19 10:30"
}
if order_id in mock_logistics_data:
return mock_logistics_data[order_id]
else:
return f"查询不到单号为{order_id}的信息,请检查单号是否正确"
# 对外暴露的接口
__all__ = ["query_logistics"]
🔍 @tool 装饰器做了什么?
只需添加@tool,LangChain会自动完成以下工作:
| 自动生成内容 | 说明 |
|---|---|
| 工具名称 | 函数名 query_logistics |
| 工具描述 | 函数的docstring(LLM据此判断何时调用) |
| 参数Schema | 根据函数签名自动解析(order_id: str) |
| 输入/输出格式 | 封装为Tool类,符合Agent调用协议 |
🧪 测试工具是否正常工作
from tools.logistics_tools import query_logistics
# 直接调用测试
print(query_logistics.invoke({"order_id": "SF123456"}))
# 输出:【顺丰速运】已揽收|广州市天河区→北京市朝阳区|预计1天送达
print(query_logistics.invoke({"order_id": "INVALID001"}))
# 输出:查询不到单号为INVALID001的信息,请检查单号是否正确
🔗 将工具绑定到LLM
from langchain_openai import ChatOpenAI
from tools.logistics_tools import query_logistics
llm = ChatOpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url=os.getenv("BASE_URL"),
model=os.getenv("LLM_MODEL"),
)
# 绑定工具(让LLM知道它能调用这个函数)
llm_with_tools = llm.bind_tools([query_logistics])
# Agent就会自动识别物流查询请求
response = llm_with_tools.invoke("帮我查一下顺丰单号SF123456的物流信息")
print(response.tool_calls) # 会输出LLM决定调用的工具及参数
💡 设计要点
- docstring 至关重要:LLM通过它理解工具的用途和适用场景,务必写清楚“什么情况用这个工具”
- 输入类型提示:
order_id: str帮助LLM正确提取参数 - 模拟数据先行:开发阶段可以用mock数据快速验证流程,后期只需替换
mock_logistics_data为真实API调用,Agent无需改动 __all__规范导出:便于模块化管理,避免意外暴露内部函数
4️⃣ Agent核心构建:创建智能执行器
有了工具和模型之后,下一步就是将两者组装成一个能够自主决策的Agent。本章展示如何使用create_agent快速构建Agent,并封装一个简单的执行器来规范化输入输出。
🤖 Agent构建代码(agent.py)
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from tools.logistics_tools import query_logistics
from langchain_core.messages import HumanMessage
# 加载环境变量
load_dotenv()
# 初始化LLM
llm = ChatOpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url=os.getenv("BASE_URL"),
model=os.getenv("LLM_MODEL"),
temperature=0.1 # 温度:0=精准回答,1=创意回答
)
# 定义可用工具集
tools = [query_logistics]
# 创建Agent
agent = create_agent(
model=llm,
tools=tools,
system_prompt=(
"你是专业的物流助手,只能使用提供的工具查询物流信息,禁止编造答案。"
"只能回答物流相关的问题,查询完成后直接返回结果。"
)
)
📦 封装Agent执行器
为了方便调用和管理,我们创建一个AgentExecutor类来规范化输入输出格式:
class AgentExecutor:
def __init__(self, agent):
self.agent = agent
def invoke(self, data):
# 提取用户输入
user_input = data["input"]
messages = [HumanMessage(content=user_input)]
# 调用Agent执行
result = self.agent.invoke({"messages": messages})
# 提取最终答案(消息列表的第4条,索引3)
answer = result["messages"][3].content
return {"output": answer}
# 实例化并导出
agent_executor = AgentExecutor(agent)
__all__ = ["agent_executor"]
🔄 Agent执行流程解析
当用户输入"查询SF123456信息"时,内部消息流转如下:
| 步骤 | 消息类型 | 内容 | 说明 |
|---|---|---|---|
| 1 | HumanMessage | 查询SF123456信息 | 用户原始输入 |
| 2 | AIMessage | 调用query_logistics(order_id="SF123456") | LLM决策调用工具 |
| 3 | ToolMessage | 【顺丰速运】已揽收… | 工具返回结果 |
| 4 | AIMessage | 根据查询结果,该订单当前状态为… | LLM生成最终回复 |
🧪 测试执行器
from agent import agent_executor
# 正常查询
result = agent_executor.invoke({"input": "帮我查一下SF123456的物流"})
print(result["output"])
# 输出:该订单【顺丰速运】已揽收,正在从广州市天河区发往北京市朝阳区,预计1天送达。
# 异常单号
result = agent_executor.invoke({"input": "查一下ABC999999"})
print(result["output"])
# 输出:查询不到单号为ABC999999的信息,请检查单号是否正确。
# 非物流问题(Agent会拒绝回答)
result = agent_executor.invoke({"input": "今天天气怎么样?"})
print(result["output"])
# 输出:抱歉,我是物流助手,只能回答物流相关的问题。
💡 关键设计说明
| 设计点 | 说明 |
|---|---|
temperature=0.1 | 低温度保证回答稳定、不跑偏,适合工具调用类任务 |
system_prompt 约束 | 明确限制Agent行为边界:只用工具、不编造、只回答物流问题 |
result["messages"][3].content | 固定取第4条消息作为最终答案(可根据实际结构调整) |
| 执行器封装 | 统一{"input": str} -> {"output": str}接口,便于后续集成 |
⚠️ 注意事项
create_agent是LangChain 1.x 版本的新API(langchain.agents),旧版本可能使用create_react_agent,请确保依赖版本正确- 消息索引
[3]依赖固定流程(Human → AI(tool_call) → Tool → AI),如果Agent有多次工具调用,需要更复杂的提取逻辑。简单场景下此方式足够
5️⃣ 主入口:构建交互式Agent应用
有了Agent执行器之后,最后一步就是创建一个用户友好的命令行交互界面。本章展示如何将前面的所有模块整合起来,形成一个完整的、可运行的物流查询助手应用。
🚀 主入口代码(main.py)
# 项目入口文件:物流助手AI Agent
from agent import agent_executor
# 程序主入口
if __name__ == "__main__":
# 欢迎界面
print("=" * 55)
print("🤖 物流查询助手 AI Agent 已启动")
print("💡 支持:物流单号查询 | 输入 exit 退出程序")
print("=" * 55)
# 循环对话
while True:
# 获取用户输入
user_query = input("\n请输入你的问题:").strip()
# 退出指令
if user_query.lower() in ["exit", "quit", "退出"]:
print("\n👋 感谢使用,祝你生活愉快!")
break
# 空输入处理
if not user_query:
print("⚠️ 请输入有效的物流查询问题~")
continue
try:
# 调用AI Agent核心逻辑
result = agent_executor.invoke({"input": user_query})
# 打印结果
print(f"\n✅ 助手回复:{result['output']}")
except Exception as e:
print(f"\n❌ 出错啦:{str(e)}")
🎮 运行效果演示
python main.py
示例对话流程:
=======================================================
🤖 物流查询助手 AI Agent 已启动
💡 支持:物流单号查询 | 输入 exit 退出程序
=======================================================
请输入你的问题:帮我查一下SF123456
✅ 助手回复:该订单【顺丰速运】已揽收,正在从广州市天河区发往北京市朝阳区,预计1天送达。
请输入你的问题:JD345678现在到哪了?
✅ 助手回复:该订单【京东物流】正在派送中,快递员李师傅,联系电话138****1234。
请输入你的问题:查一下ABC999999
✅ 助手回复:查询不到单号为ABC999999的信息,请检查单号是否正确。
请输入你的问题:今天天气怎么样?
✅ 助手回复:抱歉,我是物流助手,只能回答物流相关的问题。
请输入你的问题:exit
👋 感谢使用,祝你生活愉快!
📁 完整项目结构
到目前为止,我们的项目文件组织如下:
logistics-agent/
│
├── .env # 环境变量(API Key、Base URL、模型名称)
├── requirements.txt # Python依赖列表
│
├── tools/
│ └── logistics_tools.py # 物流查询工具定义(query_logistics)
│
├── agent.py # Agent核心 + AgentExecutor封装
├── main.py # 主入口(命令行交互界面)
│
└── README.md # 项目说明文档(可选)
🔄 完整调用链路图
6️⃣ 运行与扩展
🚀 快速启动
- 克隆/创建项目文件夹
- 安装依赖:
pip install -r requirements.txt - 配置环境变量:在
.env文件中填入你的DASHSCOPE_API_KEY - 运行程序:
python main.py
🔧 扩展建议
| 扩展方向 | 实现方式 | 难度 |
|---|---|---|
| 接入真实物流API | 替换mock_logistics_data为调用快递100、菜鸟裹裹等真实接口 | ⭐⭐ |
| 增加更多工具 | 添加天气查询、地图导航、订单追踪等工具 | ⭐⭐ |
| 添加记忆功能 | 使用langgraph-checkpoint让Agent记住对话历史 | ⭐⭐⭐ |
| Web化部署 | 用FastAPI包装agent_executor,提供RESTful API | ⭐⭐ |
| 流式输出 | 使用.stream()方法实现逐字输出效果 | ⭐⭐ |
| 多模型切换 | 支持GPT-4、Claude、文心一言等不同模型 | ⭐⭐ |
| 添加数据库 | 存储查询记录,实现历史查询统计 | ⭐⭐⭐ |
📚 写在最后
至此,我们已经完成了一个完整的AI Agent项目:
- ✅ 环境搭建与依赖配置
- ✅ 通义千问模型接入
- ✅ 自定义工具定义与绑定
- ✅ Agent构建与执行器封装
- ✅ 命令行交互界面
这个项目虽然简单,但包含了Agent开发的核心思想:LLM作为大脑 + 工具作为手脚 + 系统提示作为行为准则。你可以基于这个模板,轻松扩展出更复杂的Agent应用(如客服机器人、数据分析助手、自动化流程编排等)。
🔗 参考资源
希望这篇博客对你有帮助!有问题欢迎在评论区交流讨论~ 🎉
如果觉得有用,别忘了点赞+收藏支持一下!
367



被折叠的 条评论
为什么被折叠?



