软工第四次作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class56-Grade2024-CS
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class56-Grade2024-CS/homework/16760
这个作业的目标 构建一个具备语言交互(会说)和行动执行(会做)能力的智能体(Agent)
学号 侯宇鹏(3124005133)

冰箱食材管家:会查库存、荐菜谱、生成并修改晚餐计划的 AI Agent

一、项目简介

我们小组实现了一个“冰箱食材管家”Web 应用。用户可以用自然语言询问冰箱里还有什么食材、今晚适合做什么菜、需要补买哪些东西;Agent 会调用库存数据库和菜谱 API 执行查询、生成菜谱计划、修改计划并生成购物清单,再用中文回复用户。

项目代码:https://github.com/Eiysia-HYP/fridge-meal-agent
项目使用 Python 3.11+、FastAPI、SQLite 和 Jinja2 构建后端与简洁 Web 页面。聊天模型通过 DashScope 的 OpenAI 兼容 Chat Completions 接口调用,默认模型配置为 qwen-plus。菜谱数据优先调用 TheMealDB 公开 API,调用失败时降级到本地菜谱缓存并明确提示。后端使用 FastMCP 暴露库存与菜谱工具,聊天 Agent 通过 Function Calling 机制与工具交互;同时保留了直接服务调用作为降级方案。

本项目的智能体具备以下特征:

  • 能说:支持自然语言多轮对话,前端支持语音输入和回复朗读。
  • 会做:能查询/修改冰箱库存、搜索菜谱、生成晚餐计划、修改计划、生成购物清单。
  • 有记忆:通过 sessionId 保存用户偏好、忌口、人数、最近计划等上下文。
  • 连外部服务:调用 TheMealDB 菜谱 API,并读写 SQLite 库存数据库。
  • 有界面:提供简洁聊天页,展示库存卡片、菜谱卡片、结构化计划和购物清单。

二、需求描述

“冰箱里有什么、能做什么、还缺什么”是日常做饭中的高频问题。只让模型生成菜谱,容易出现使用不存在食材、忽略忌口、重复推荐或购物清单不准确的问题。因此,本项目实现一个能对话并能调用工具的食材管家 Agent,把自然语言需求转化为对库存数据库和菜谱服务的真实操作。

项目主要需求如下:

  1. 用户可用自然语言查询冰箱库存,例如“冰箱里还有多少鸡蛋和西红柿?”
  2. 用户可提出做饭需求,例如“今晚两个人吃,忌辣,用现有食材推荐三道菜”。
  3. Agent 必须调用库存工具和菜谱工具,不能编造库存或菜谱数据。
  4. 计划需包含菜名、所需食材、库存匹配情况、缺少食材、简单步骤和忌口提示。
  5. 用户可在多轮对话中修改人数、口味、忌口或某道菜;未要求修改的条件应尽量保留。
  6. 用户可要求生成购物清单,Agent 根据计划与库存差额生成清单。
  7. 支持语音输入和语音朗读回复。
  8. 提供简洁 Web 前端,并保留传统库存查询页面和菜谱搜索页面。

三、业务流程

用户语音/文本输入
       ↓
浏览器语音识别 ASR(可选)→ 文本填入聊天框
       ↓
用户在 /chat 输入自然语言
       ↓
POST /api/chat 携带 sessionId 和 message
       ↓
读取会话记忆:人数、忌口、偏好、最近计划、库存摘要
       ↓
DashScope 兼容模型理解意图并选择工具
       ↓
┌──────────────────────────────────────┐
│ get_inventory       → 查询 SQLite 库存 │
│ add_inventory       → 增加库存         │
│ remove_inventory    → 扣减库存         │
│ search_recipes      → 调用 TheMealDB   │
│ generate_meal_plan  → 生成菜谱计划     │
│ modify_meal_plan    → 修改计划         │
│ generate_shopping_list → 生成购物清单  │
└──────────────────────────────────────┘
       ↓
Agent 根据工具真实返回组织中文回复
       ↓
页面展示回复、库存卡片、菜谱卡片、计划或购物清单
       ↓
浏览器 TTS 朗读 Agent 回复(可选)

四、实现说明

  1. 自然语言交互与模型调用
    用户通过 /chat 页面输入消息,前端调用 POST /api/chat。请求携带 sessionId 和必填的 message。后端将当前对话历史、会话记忆和工具定义发送给支持 OpenAI Chat Completions 工具调用格式的模型。模型可以返回普通文本,也可以请求调用库存、菜谱或计划工具;后端执行工具后将结果交回模型,形成“理解需求—调用工具—根据真实结果回复”的闭环。

  2. 多轮对话记忆
    会话由 sessionId 区分。SQLite 中保存消息历史、用户人数、忌口、口味偏好、最近菜谱计划和最近购物清单;会话 30 分钟无活动后标记过期。多轮记忆使 Agent 可以处理类似“把主菜换成鱼,不要花生”的后续指令:Agent 会复用当前会话中的人数、忌口和已有计划,只修改用户指定菜品,并尽量保留其他未修改内容。

  3. 语音输入与语音输出
    前端在聊天输入区提供“语音输入”和“朗读回复”能力:

语音输入:使用浏览器 Web Speech API 将语音转成文字,填入聊天框,用户确认后发送。

语音输出:使用 speechSynthesis 朗读 Agent 回复,支持手动开启/关闭。

降级策略:浏览器不支持语音能力时,自动降级为纯文本输入输出。

  1. 外部 API 与数据库交互
    项目通过 SQLite 管理冰箱库存和会话记忆,主要表包括:inventory(库存)、sessions(记忆)、messages(消息)、recipes_cache(菜谱缓存)。

菜谱搜索优先调用 TheMealDB 公开 API,将结果标准化后写入缓存;外部 API 超时或不可用时,使用本地缓存并明确提示“当前使用缓存菜谱”。库存写操作需要用户明确确认,避免模型误改数据。

  1. 工具与 MCP 接入
    后端使用 FastMCP 暴露以下工具:get_inventory、add_inventory、remove_inventory、search_recipes、generate_meal_plan、modify_meal_plan、generate_shopping_list。聊天 Agent 通过 Function Calling 发现并调用这些工具,只向模型提供约定的工具白名单。

  2. 计划生成与业务规则
    忌口/过敏:作为硬约束,计划中不得出现相关食材。

库存优先:优先推荐库存可覆盖的菜谱。

缺料提示:缺少食材写入购物清单,不虚构库存。

外部 API 失败:使用缓存菜谱并明确说明。

五、使用示例

image

示例一:语音查询库存

用户点击“语音输入”,说出:“冰箱里还有多少鸡蛋和西红柿?”

Agent 执行:调用 get_inventory 查询 SQLite 库存。

Agent 回复:根据真实库存说明数量;若某项不存在,明确说明未记录,不编造数量。

示例二:生成晚餐计划

用户:今晚两个人吃,忌辣,用现有食材推荐三道菜。

Agent 执行:调用 get_inventory 获取库存,调用 search_recipes 搜索菜谱,再调用 generate_meal_plan 生成计划。

页面结果:三道菜的名称、所需食材、库存匹配情况、缺少食材、简要步骤和忌口提示。

示例三:多轮修改

用户:把主菜换成鱼,不要花生。

Agent 执行:读取当前会话中的人数、忌口和已有计划,调用 modify_meal_plan 只调整主菜,保留其他菜品和条件。

Agent 回复:说明修改后的主菜和仍需补买的食材;工具调用结果由后端实际执行后记录。

示例四:生成购物清单

用户:把缺的东西整理成购物清单。

Agent 执行:调用 generate_shopping_list,根据计划和库存差额生成清单。

六、运行与验证方式

本项目已部署在 GitHub Codespaces 云端环境,无需本地配置 Python 环境即可运行。

启动步骤:

在 GitHub 仓库中点击 Code -> Codespaces -> Create codespace on main。

在终端(Terminal)中安装依赖:

bash
pip install -r requirements.txt
配置环境变量(需提前在阿里云百炼平台获取 DashScope API Key):

bash
export DASHSCOPE_API_KEY="sk-你的真实Key"
启动应用:

bash
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000
点击右下角弹出的 "Open in Browser" 即可体验。

七、小组分工

无

八、GitHub链接

https://github.com/Eiysia-HYP/fridge-meal-agent

九、心得

通过这次作业,我对 AI Agent 有了更具体的认识。以前觉得 AI 只是“一问一答”的聊天机器人,现在通过调用外部 API、操作 SQLite 数据库,让它真正具备了“动手做”的能力,解决了实际问题。

在开发过程中,我也遇到了不少挑战,比如多轮对话状态怎么保持、环境依赖冲突导致报错等。特别是在排查 Starlette 版本兼容和部署云端环境时,我学会了看终端日志、定位问题并独立解决。

posted @ 2026-10-25 12:32  ElysiaP  阅读(22)  评论(0)    收藏  举报