基于LangChain与Agent的智能无人机租赁系统开发实战
2026/9/2 5:48:33 网站建设 项目流程

这类项目最值得关注的不是“AI+无人机”这个组合本身,而是如何用 LangChain 和 Agent 把“租赁”这个业务流程真正自动化、智能化起来。它适合两类人:一是需要做毕业设计或课程设计的学生,想找一个有完整前后端、有实际业务逻辑、又能结合大模型热点的项目;二是准备面试的开发者,需要一个能讲清楚从需求拆解、技术选型到核心模块实现的综合案例。

很多人一看到“AI无人机”就觉得是视觉识别、自动飞行,但在这个租赁系统里,AI 的核心是处理用户对话、理解租赁意图、自动执行查询和预订流程。LangChain 负责编排调用链,Agent 负责决策和工具调用,这才是项目的技术骨架。下面我会按实际开发的顺序,从环境搭建到核心模块,拆解一遍实现思路和关键代码,确保你能跑起来,也能讲明白。

1. 先理清业务,再确定技术栈:这个系统到底要做什么?

在动手写代码之前,必须把“无人机租赁”这个业务场景拆解成具体的功能模块和流程。这决定了你的数据库设计、接口设计和 Agent 的决策逻辑。

1.1 核心业务流程与功能模块

一个典型的无人机租赁系统,用户侧的核心流程是:查询 -> 选择 -> 预订 -> 支付 -> 取机/还机 -> 评价。后台则需要管理无人机库存、订单、用户和财务。

基于此,我们可以梳理出以下核心模块:

  • 用户模块:注册、登录、个人信息管理。
  • 无人机管理模块:无人机信息的增删改查(型号、品牌、续航、载重、日租金、库存状态、图片等)。
  • 租赁订单模块:创建订单、查看订单历史、取消订单、支付状态管理。
  • 库存与调度模块:这是业务核心,需要根据租赁时间实时更新无人机可用状态,防止超租。
  • 智能客服与导租模块(AI Agent核心):这就是 LangChain + Agent 的用武之地。用户可以通过自然语言与系统交互,例如:“我想租一台能航拍4K、续航30分钟以上的无人机,这周末用。” Agent 需要理解这个请求,调用工具(比如查询数据库)找到符合条件的无人机,并引导用户完成预订。

1.2 技术选型与架构设计

根据上述业务,一个可行的全栈技术选型如下:

  • 后端:Python + FastAPI(轻量、异步支持好,适合快速构建API)。数据库用 PostgreSQL 或 MySQL。
  • AI 核心:LangChain + 大模型 API(如 OpenAI GPT、国内智谱、月之暗面等)。用 LangChain 来构建 Agent,定义工具(Tools),并管理对话记忆(Memory)。
  • 前端:Vue.js 或 React,用于构建管理后台和用户页面。对于课程设计,也可以用简单的 HTML + JavaScript 演示核心交互。
  • 其他:Redis(用于缓存和会话管理)、Celery(可选,用于处理异步任务,如发送邮件、库存同步)。

整个系统的数据流大致是:前端请求 -> FastAPI 后端 -> 根据路由,如果是普通API则直接处理;如果是自然语言请求,则交给 LangChain Agent 处理 -> Agent 分析意图,决定调用哪个工具(如search_drones)-> 工具执行(如查询数据库)-> 结果返回给 Agent -> Agent 组织语言回复给前端。

2. 搭建基础环境与项目骨架

不要一上来就写复杂的 Agent 逻辑。先把 Web 服务和数据库的基础架子搭好,确保基础功能(如用户登录、无人机列表)能跑通。

2.1 项目初始化与依赖安装

创建一个标准的 Python 项目目录,并使用requirements.txt管理依赖。

# 创建项目目录 mkdir ai-drone-rental && cd ai-drone-rental mkdir app api core agents tools models schemas utils touch main.py requirements.txt .env # 一个精简的 requirements.txt 示例 fastapi==0.104.1 uvicorn[standard]==0.24.0 sqlalchemy==2.0.23 pydantic==2.5.0 python-dotenv==1.0.0 langchain==0.0.340 langchain-openai==0.0.2 # 如果你用OpenAI openai==1.3.0 redis==5.0.1 celery==5.3.4

使用虚拟环境安装依赖:pip install -r requirements.txt

2.2 数据库模型设计(SQLAlchemy)

models/目录下定义核心的数据表。这里的关键是Drone(无人机)和RentalOrder(租赁订单)模型,它们直接关联库存逻辑。

# models/drone.py from sqlalchemy import Column, Integer, String, Float, Boolean, DateTime from sqlalchemy.sql import func from core.database import Base class Drone(Base): __tablename__ = "drones" id = Column(Integer, primary_key=True, index=True) name = Column(String(100), nullable=False) # 型号名称 brand = Column(String(50)) max_flight_time = Column(Integer) # 最大续航(分钟) camera_quality = Column(String(50)) # 如 “4K” daily_rate = Column(Float, nullable=False) # 日租金 total_inventory = Column(Integer, default=1) # 总库存 available_inventory = Column(Integer, default=1) # 当前可用库存 is_active = Column(Boolean, default=True) created_at = Column(DateTime(timezone=True), server_default=func.now()) # models/order.py class RentalOrder(Base): __tablename__ = "rental_orders" id = Column(Integer, primary_key=True, index=True) user_id = Column(Integer, index=True) drone_id = Column(Integer, index=True) start_date = Column(DateTime, nullable=False) end_date = Column(DateTime, nullable=False) total_amount = Column(Float) status = Column(String(20), default='pending') # pending, confirmed, cancelled, completed created_at = Column(DateTime(timezone=True), server_default=func.now())

注意Drone模型中的available_inventory是关键。每次创建有效订单时,需要原子性地减少它;订单取消或完成后,再增加回来。这需要在业务逻辑层做严格的并发控制,防止超租。

2.3 实现基础 CRUD API(FastAPI)

api/目录下创建路由。先实现最简单的无人机查询接口,这是后续 Agent 工具的基础。

# api/drones.py from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from models.drone import Drone from schemas.drone import DroneOut from core.database import get_db router = APIRouter(prefix="/drones", tags=["drones"]) @router.get("/", response_model=list[DroneOut]) def list_drones( db: Session = Depends(get_db), skip: int = 0, limit: int = 100, min_flight_time: int = Query(None, ge=0), max_daily_rate: float = Query(None, ge=0) ): """查询无人机列表,支持基础过滤""" query = db.query(Drone).filter(Drone.is_active == True) if min_flight_time is not None: query = query.filter(Drone.max_flight_time >= min_flight_time) if max_daily_rate is not None: query = query.filter(Drone.daily_rate <= max_daily_rate) drones = query.offset(skip).limit(limit).all() return drones

到这一步,你应该能通过uvicorn main:app --reload启动服务,并访问/docs看到 Swagger 文档,测试/drones/接口返回数据。这是后续所有复杂功能的基石。

3. 构建 AI Agent 核心:LangChain 工具与智能体

这是项目的亮点,也是面试时最能体现你技术深度的部分。重点不是调用 API,而是设计合理的工具(Tools)和清晰的 Agent 执行流程。

3.1 设计 Agent 所需的工具(Tools)

Agent 本身不直接查数据库,它通过“工具”与外界交互。我们需要把业务能力封装成工具。至少需要以下几个:

  1. 搜索无人机工具:根据用户自然语言描述(如“续航长的”、“便宜的”、“能拍4K的”)查询数据库。
  2. 查询订单状态工具:根据用户ID或订单号查询历史订单。
  3. 创建租赁订单工具:用户选定无人机和日期后,Agent 调用此工具创建订单。

首先,实现一个工具函数,它将被 LangChain 包装。

# tools/drone_search.py from typing import Optional, Dict, Any from sqlalchemy.orm import Session from models.drone import Drone from core.database import SessionLocal def search_available_drones( camera_quality: Optional[str] = None, min_flight_time: Optional[int] = None, max_daily_rate: Optional[float] = None ) -> str: """ 根据条件搜索可用无人机。 返回一个格式化的字符串结果,供Agent阅读。 """ db: Session = SessionLocal() try: query = db.query(Drone).filter( Drone.is_active == True, Drone.available_inventory > 0 ) if camera_quality: query = query.filter(Drone.camera_quality.ilike(f"%{camera_quality}%")) if min_flight_time: query = query.filter(Drone.max_flight_time >= min_flight_time) if max_daily_rate: query = query.filter(Drone.daily_rate <= max_daily_rate) drones = query.order_by(Drone.daily_rate).all() if not drones: return "目前没有找到符合您条件的可用无人机。" result_lines = [] for drone in drones: result_lines.append( f"- 型号:{drone.name} (品牌:{drone.brand}), " f"续航:{drone.max_flight_time}分钟, " f"相机:{drone.camera_quality}, " f"日租金:¥{drone.daily_rate}, " f"可用数量:{drone.available_inventory}" ) return "找到以下符合您条件的无人机:\n" + "\n".join(result_lines) finally: db.close()

3.2 使用 LangChain 创建 Agent

现在,我们用 LangChain 将上面的函数包装成 Tool,并创建一个能够使用这些工具的 Agent。

# agents/drone_rental_agent.py import os from langchain.agents import AgentExecutor, create_openai_tools_agent from langchain_openai import ChatOpenAI from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain.tools import Tool from langchain.memory import ConversationBufferMemory from tools.drone_search import search_available_drones from tools.order_tools import get_user_orders, create_rental_order # 假设其他工具也已实现 # 1. 定义工具列表 tools = [ Tool( name="SearchDrones", func=search_available_drones, description="""当用户想租赁无人机、查询无人机信息或询问有什么无人机可选时,使用此工具。 输入应该是一个包含以下可选键的JSON字符串:camera_quality(相机质量,如'4K')、 min_flight_time(最小续航分钟数)、max_daily_rate(最高日租金)。""" ), # Tool(name="GetMyOrders", func=get_user_orders, description="..."), # Tool(name="CreateOrder", func=create_rental_order, description="..."), ] # 2. 设置LLM和Prompt llm = ChatOpenAI( model="gpt-3.5-turbo-1106", # 或 gpt-4 temperature=0, openai_api_key=os.getenv("OPENAI_API_KEY") ) # 系统提示词至关重要,它定义了Agent的角色和能力边界 system_prompt = """你是一个专业的无人机租赁助手。你的职责是帮助用户查询可租赁的无人机、查看订单状态以及创建新的租赁订单。 请遵循以下规则: 1. 首先,友好地问候用户并了解他们的需求。 2. 如果用户想找无人机,先使用`SearchDrones`工具查询,然后根据结果向用户推荐。 3. 如果用户想创建订单,你需要先确认无人机型号、租赁开始和结束日期,然后使用`CreateOrder`工具。 4. 如果用户想查看订单,使用`GetMyOrders`工具。 5. 始终以清晰、有条理的方式呈现信息。 6. 如果你无法处理用户请求,请礼貌地告知并建议他们联系人工客服。""" prompt = ChatPromptTemplate.from_messages([ ("system", system_prompt), MessagesPlaceholder(variable_name="chat_history"), ("human", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad"), ]) # 3. 创建Agent和Executor,并加入记忆 memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) agent = create_openai_tools_agent(llm, tools, prompt) agent_executor = AgentExecutor(agent=agent, tools=tools, memory=memory, verbose=True) # 4. 调用示例 if __name__ == "__main__": # 模拟一个对话 response = agent_executor.invoke({"input": "你好,我想租一台能拍4K视频的无人机,预算每天不超过500块。"}) print(response["output"])

关键点

  • 提示词工程system_prompt是 Agent 的“大脑”,必须清晰定义其角色、步骤和边界。写得越具体,Agent 行为越可控。
  • 工具描述Tooldescription字段是给 LLM 看的说明书,它根据这个来决定是否以及如何调用工具。描述要准确、包含输入格式。
  • 记忆(Memory)ConversationBufferMemory让 Agent 能记住对话上下文,实现多轮交互。这对于租赁这种需要多次确认信息的场景是必须的。
  • Verbose 模式:开发时设置verbose=True,可以在控制台看到 Agent 的思考链(ReAct),极大方便调试。

4. 将 Agent 集成到 Web 服务并提供 API

Agent 不能只在脚本里跑,需要提供一个 HTTP 接口供前端调用。同时,需要考虑用户会话隔离(每个前端用户应有独立的 Agent 记忆)。

4.1 创建 Agent 服务层与会话管理

我们不能为每个请求都创建一个新的AgentExecutorMemory,这样会丢失历史。需要用一个字典来管理以user_idsession_id为键的 Agent 实例。

# agents/agent_manager.py from langchain.memory import ConversationBufferMemory from .drone_rental_agent import create_agent_executor # 假设我们把创建逻辑封装成了函数 class AgentManager: def __init__(self): self.user_agents = {} # {session_id: agent_executor} def get_agent_for_session(self, session_id: str): """获取或创建一个属于某个会话的Agent""" if session_id not in self.user_agents: memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) agent_executor = create_agent_executor(memory) # 传入memory创建 self.user_agents[session_id] = agent_executor return self.user_agents[session_id] def clear_session(self, session_id: str): """清除某个会话的Agent和记忆""" if session_id in self.user_agents: del self.user_agents[session_id] agent_manager = AgentManager()

4.2 提供聊天 API 端点

在 FastAPI 中创建一个新的路由来处理与 AI 助手的对话。

# api/chat.py from fastapi import APIRouter, HTTPException, Header from pydantic import BaseModel from agents.agent_manager import agent_manager import uuid router = APIRouter(prefix="/ai", tags=["ai-assistant"]) class ChatRequest(BaseModel): message: str session_id: str | None = None # 前端可传递已有的session_id class ChatResponse(BaseModel): reply: str session_id: str @router.post("/chat", response_model=ChatResponse) async def chat_with_agent(request: ChatRequest): """ 与无人机租赁AI助手对话。 如果未提供session_id,将生成一个新的,用于保持多轮对话上下文。 """ session_id = request.session_id or str(uuid.uuid4()) agent = agent_manager.get_agent_for_session(session_id) try: result = agent.invoke({"input": request.message}) reply = result["output"] except Exception as e: # 处理Agent执行中的错误,如工具调用失败、LLM API异常等 raise HTTPException(status_code=500, detail=f"AI助手处理请求时出错: {str(e)}") return ChatResponse(reply=reply, session_id=session_id)

现在,前端就可以通过向/ai/chat发送 POST 请求(携带message和可选的session_id)来与 AI 租赁助手交互了。助手会根据对话历史,调用合适的工具来回答问题或执行操作。

5. 核心业务逻辑实现与避坑指南

有了 AI 交互,基础业务逻辑的健壮性同样重要。这里最容易出问题的是库存并发和订单状态机。

5.1 库存扣减与并发控制

当多个用户同时预订同一台无人机时,简单的“查询-判断-更新”流程会导致超租。必须使用数据库的悲观锁或乐观锁。

使用数据库行锁(悲观锁)示例:

# services/order_service.py from sqlalchemy import select from sqlalchemy.orm import Session from models.drone import Drone from models.order import RentalOrder import datetime def create_rental_order_with_lock(db: Session, user_id: int, drone_id: int, start_date: datetime, end_date: datetime): # 1. 开始一个数据库事务 with db.begin(): # 2. 使用 with_for_update() 锁定要操作的无人机行 drone = db.execute( select(Drone).where(Drone.id == drone_id, Drone.is_active == True).with_for_update() ).scalar_one_or_none() if not drone: raise ValueError("无人机不存在或已下架") if drone.available_inventory < 1: raise ValueError("该型号无人机暂无库存") # 3. 在锁内扣减库存 drone.available_inventory -= 1 # 4. 创建订单 days = (end_date - start_date).days + 1 total_amount = days * drone.daily_rate new_order = RentalOrder( user_id=user_id, drone_id=drone_id, start_date=start_date, end_date=end_date, total_amount=total_amount, status='confirmed' ) db.add(new_order) # 5. commit时,锁释放,更改持久化 db.commit() return new_order # 如果中间任何步骤失败,事务回滚,锁释放,库存不会错误扣减。

5.2 订单状态流转与定时任务

订单有生命周期(pending, confirmed, cancelled, completed)。需要一个后台任务(如 Celery Beat)定期扫描已过end_dateconfirmed订单,将其标记为completed,并释放无人机库存。

# tasks/order_tasks.py from celery import Celery from core.database import SessionLocal from models.order import RentalOrder from models.drone import Drone import datetime celery_app = Celery('tasks', broker='redis://localhost:6379/0') @celery_app.task def check_and_complete_orders(): """定时任务:检查并完成已结束的订单""" db = SessionLocal() try: now = datetime.datetime.now() # 查找租赁结束时间已到且状态为 confirmed 的订单 expired_orders = db.query(RentalOrder).filter( RentalOrder.end_date < now, RentalOrder.status == 'confirmed' ).all() for order in expired_orders: order.status = 'completed' # 释放库存 drone = db.query(Drone).filter(Drone.id == order.drone_id).first() if drone: drone.available_inventory += 1 db.commit() finally: db.close()

你需要配置 Celery Worker 和 Beat 来执行这个定时任务。

5.3 前端与 Agent 的协同

前端界面需要两个主要部分:

  1. 传统功能页面:用户管理、无人机列表浏览、订单列表等。
  2. AI 聊天窗口:一个类似聊天框的组件,用于与/ai/chat接口通信,并维护session_id

在聊天窗口中,当 Agent 通过工具搜索到无人机列表时,前端可以解析回复(或让 Agent 返回结构化数据),并高亮展示相关无人机,甚至提供“立即预订”按钮,点击后调用传统的订单创建 API。这实现了 AI 引导与最终操作的闭环。

6. 项目部署、扩展与面试要点

6.1 基础部署

对于课程设计或毕设演示,最简单的部署方式是:

  1. 后端:在云服务器上用nohupsystemd运行uvicorn
  2. 数据库:使用云数据库服务或本地 Docker 运行的 PostgreSQL。
  3. 前端:使用npm run build生成静态文件,由 Nginx 提供服务。
  4. 环境变量:务必通过.env文件管理敏感信息,如数据库连接串、大模型 API Key,并确保.env文件在.gitignore中。

6.2 可能的扩展方向

要让项目更出彩,可以考虑:

  • 多模态:让 Agent 不仅能处理文本,还能接收用户上传的航拍场景图片,并推荐合适的无人机型号(需要结合视觉描述模型)。
  • 复杂工具调用:集成支付网关工具(模拟)、天气查询工具(租赁日期若下雨则提醒用户)、物流工具(模拟配送)。
  • 使用 LangGraph:如果租赁流程非常复杂(如先询价、再选保险、再选择配件),可以使用 LangGraph 来定义更清晰的状态图和流程。
  • 评估与监控:记录用户与 Agent 的对话日志,评估工具调用的准确率和用户满意度。

6.3 面试时如何讲解这个项目

如果你在简历或面试中提及此项目,建议按以下逻辑阐述:

  1. 业务理解:先一句话说清系统做什么(一个基于自然语言交互的无人机租赁平台)。
  2. 技术架构:点明核心是“FastAPI 后端 + LangChain Agent 中间层 + 传统数据库/业务逻辑”。
  3. 我的角色:重点讲清楚你如何设计 Agent 的提示词(System Prompt)和工具(Tools),这是思维能力的体现。
  4. 难点与解决:提及库存并发控制(悲观锁)、Agent 会话管理、工具函数的设计与封装。
  5. 结果与思考:演示一个完整的对话流程(用户询问 -> Agent 理解并调用工具 -> 返回结果 -> 引导下单)。并讨论局限性,比如 LLM 可能“幻觉”出不存在的信息,以及如何通过严格的工具输入验证和错误处理来缓解。

这个项目的价值在于,它不是一个简单的 CRUD 系统,也不是一个纯 AI 对话 demo,而是将 AI Agent 技术落地到一个有完整业务闭环的真实场景中。从环境搭建、数据库设计、API 编写,到最核心的 Agent 编排和工具调用,每一步都踩一遍,你对“AI 应用开发”的理解会扎实很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询