作者想说的话:目前面临严峻的就业形势,学习了解一下Agent的开发很有必要.本篇文章也是在AI指导下完成,作者对Agent的了解不多,把自己学习的部分分享给大家,希望能让大家对Agent的有一个怯魅,这样的一个简单的CRUD_Agent可以基于我们项目中的种种落地情况,根据不同的需求再添加鉴权等等功能.
想必大家都对现在的 Agent(智能体) 特别好奇,觉得它高深莫测。其实,如果我们剥去那些高大上的名词(什么 MCP、RAG、LangGraph),它的本质非常简单:一个能听懂人话、自动调用接口的"自动化脚本"。
- 环境与准备:
- IDE: PyCharm 2026.1.2
- Python: 3.14.5
- 核心框架:
langchain, langchain-openai, requests - 前置条件:你需要有一个现成的后端项目(比如
Spring Boot),提供标准的RESTful API。本文以商品管理接口为例。
- 第一步:配置你的"大脑" (LLM)
Agent 的核心是一个大语言模型(LLM)。我们使用LangChain来封装它。
创建一个 crud_agent.py,首先引入依赖并配置模型:
ini
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool`
from langchain_core.messages import HumanMessage, SystemMessage, ToolMessage
import requests
=======*= 1. 配置 LLM =*=======
llm = ChatOpenAI(
model="deepseek-v4-flash", # 模型名称
api_key="sk-sp-XXXXX", # 你的 API Key
base_url="https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
temperature=0.1, # 温度越低,回答越严谨(CRUD 建议调低)
max_tokens=1024, # 输出文本上限
)
[#你的本地项目地址](#你的本地项目地址)
BASE_URL = "http://localhost:8080"
- 第二步:给大脑装上"手" (Tools)
LLM 本身只能聊天,它不能直接操作数据库。我们需要把后端的 API 包装成它能调用的 工具 (Tools)。
这里做一个非常有趣的类比:
在Java 中,我们用@GetMapping注解把一个方法暴露成 HTTP 接口;
在Python LangChain中,我们用@tool装饰器把一个函数暴露给 LLM。
示例:新增商品工具
python
=======*= 2. 定义工具 =*=======
@tool
def save_product(
productName: str,
productCode: str,
price: float,
stock: int,
) -> str:
"""新增商品"""
payload = {
"productName": productName,
"productCode": productCode,
"price": price,
"stock": stock,
}
# 像平时写 Java 请求一样换成了 Python 调用后端接口,
resp = requests.post(f"{BASE_URL}/product/save", json=payload)
return f"新增商品结果: {resp.text}"
这段代码发生了什么?
@tool: 这是一个装饰器。它会自动读取函数名save_product、参数类型(str, float...)以及函数的文档注释 """新增商品"""。- 注册:
LangChain会把这份"说明书"发给 LLM。LLM 就知道了:"哦,如果我需要新增商品,我应该调用save_product,并且需要提供productName等参数。" - 执行: 当 LLM 决定调用时,我们的 Python 代码就会真的去发一个 POST 请求给你的 Spring Boot 后端。
CRUD其他代码;
python
@tool`
def update_product(
productId: int,
productName: str,
productCode: str,
price: float,
stock: int,
) -> str:
"""更新商品信息(必须传入 productId)"""
payload = {
"productId": productId,
"productName": productName,
"productCode": productCode,
"price": price,
"stock": stock,
}
resp = requests.post(f"{BASE_URL}/product/update", json=payload)
return f"更新商品结果: {resp.text}"
@tool
def delete_product(product_id: int) -> str:
"""根据 ID 删除商品"""
resp = requests.delete(f"{BASE_URL}/product/delete/{product_id}")
return f"删除商品结果: {resp.text}"
@tool
def get_product(product_id: int) -> str:
"""查询单个商品的详细信息"""`
resp = requests.get(f"{BASE_URL}/product/detail/{product_id}")
return f"商品详情: {resp.text}"
@tool
def page_products(current: int = 1, size: int = 10, productName: str = "", productCode: str = "") -> str:
"""分页查询商品列表,支持按名称或编码筛选"""
payload = {}
if productName: payload["productName"] = productName
if productCode: payload["productCode"] = productCode
resp = requests.post(f"{BASE_URL}/product/page", params={"current": current, "size": size}, json=payload if payload else None)
return f"查询结果: {resp.text}"
- 第三步:让 Agent 动起来 (The Loop)
光有工具和模型还不够,我们需要一个循环来处理用户的输入。这就是 Agent 的"思考-行动"闭环:
- 用户说话 👤
- LLM 思考 🧠:我需要调用哪个工具?
- 执行工具 🔧:Python 调用后端接口
- 反馈结果 📝:把接口返回的结果告诉 LLM
- 最终回答 🤖:LLM 组织语言回复用户
#绑定工具到模型
ini
# 把我们定义好的所有工具(函数)放进一个列表里
# 这就好比给 LLM 准备了一本"技能手册"
tools = [`save_product, update_product, delete_product, get_product, page_products`]
# 把这本"技能手册"交给 LLM
# `bind_tools` 的作用是让模型知道:"嘿,你现在会这些招数了,需要的时候可以用。"
llm_with_tools = llm.bind_tools(tools)
def run_agent():
# 初始化对话历史
# SystemMessage 是给 AI 的"人设说明书",告诉它该干什么、有哪些规矩
messages = [
SystemMessage(content=(
"你是一个商品管理助手。你可以执行以下操作:\n"
"1. 新增商品 --- save_product\n"
"2. 更新商品 --- update_product\n"
"3. 删除商品 --- delete_product\n"
"4. 查询详情 --- get_product\n"
"5. 分页查询 --- page_products\n"
"请用中文总结操作结果。"
))
]
print("🤖 Agent 已启动,请输入指令(输入 exit 退出):")
# 开启一个死循环,让程序一直运行等待用户说话
while True:
user_input = input("\n👤 你说: ")
# 如果用户想退出,就跳出循环结束程序
if user_input.lower() in ["exit", "quit"]:
break
# 把用户的这句话包装成 HumanMessage,存入聊天记录
messages.append(HumanMessage(content=user_input))
# 开始思考循环(最多尝试 5 次,防止 AI 钻牛角尖出不来)
for turn in range(5):
# ★ 核心步骤:把聊天记录发给 LLM,让它决定下一步怎么做
response = llm_with_tools.invoke(messages)
# 把 LLM 的思考结果也存进历史记录,这样它才不会"失忆"
messages.append(response)`
# 检查 LLM 是不是想调用工具(比如它发现需要查数据库)
if response.tool_calls:
for tc in response.tool_calls:
tool_name = tc["name"] # 拿到工具的名字,比如 "get_product"
tool_args = tc["args"] # 拿到参数,比如 {"product_id": 1}
print(f" 🔧 正在调用工具: {tool_name} ...")
# 这是一个"路由表":根据名字找到对应的 Python 函数去执行
tool_map = {
"save_product": save_product,
"update_product": update_product,
"delete_product": delete_product,
"get_product": get_product,
"page_products": page_products
}
# 真正执行那个函数,并拿到后端返回的结果
result = tool_map[tool_name].invoke(tool_args)
print(f" ✅ 执行完成")
# ★ 关键一步:把执行结果(ToolMessage)告诉 LLM
# 这样 LLM 才知道接口调用成功了,才能组织语言回复你
messages.append(ToolMessage(content=result, tool_call_id=tc["id"]))
# 如果 LLM 这次没调工具,说明它已经可以直接回答你了
if not response.tool_calls:
print(f"\n🤖 Agent: {response.content}")
break # 这一轮对话结束,回到 input 等待下一句
if __name__ == "__main__":
run_agent()`
- 运行效果
当你运行程序并输入:
👤 你说: 帮我新增一个商品,叫华为 Mate 70,编码 HW70,价格 6999,库存 100。
控制台会显示:
🔧 正在调用工具: save_product ...
🤖 Agent: 华为 Mate 70 已成功新增!