☰
大模型Agent智能体开发实战:从零搭建餐饮服务智能体
2026/9/26 12:43:00 网站建设 项目流程

1. 从"服范-九添菜菜"这个项目名说起:一个智能体到底在解决什么问题

第一次看到"服范-九添菜菜大模型Agent智能体开发实战"这个标题,很多人会愣一下——"服范"是什么?"九添菜菜"又是什么?其实把名字拆开看就明白了:这是一个围绕餐饮服务场景做的大模型智能体项目,"服范"取的是"服务规范、服务范式"的意思,"九添菜菜"则是项目内部给这个智能体起的拟人化代号,类似给客服机器人起个花名。名字本身不重要,重要的是它背后代表的一类需求:把大模型的通用能力,收敛到一个具体业务场景里,让它能稳定、可控、可复现地完成一串任务。

我在过去一年多时间里,陆陆续续做过七八个智能体项目,从最早的"套个提示词就上线"到后来老老实实搭工作流、写工具函数、做评测集,踩的坑基本能写一本书。这个"服范-九添菜菜"项目,本质上就是一个典型的垂直场景智能体:用户(可能是餐厅顾客、也可能是门店运营)用自然语言提出需求,智能体理解意图后,调用一系列工具(查菜单、算价格、排班、生成话术、记录反馈),最后给出一个结构化或半结构化的结果。

它解决的问题很具体:传统餐饮服务里,很多环节靠人记、靠人传、靠人判断,效率低且容易出错。比如顾客问"我们六个人,预算三百,有没有推荐",一个熟练的服务员能秒答,但一个新手可能要翻半天菜单。智能体要做的,就是把这个"熟练服务员"的经验固化成可调用的能力。

适合谁看这篇内容?三类人:一是刚接触Agent开发、想找一个完整案例练手的开发者;二是业务侧想落地智能体、但不知道从哪切入的产品或运营;三是已经做过Demo、但发现"Demo很美好,上线就翻车"的同行。我会尽量把每一步的"为什么"讲清楚,而不是只丢一堆代码。

2. 智能体不是"更长的提示词":拆解九添菜菜的核心架构

2.1 为什么单纯堆提示词一定会失败

很多人做智能体的第一反应是:写一个超长的System Prompt,把菜单、规则、话术全塞进去,然后让模型自己发挥。我早期也这么干过,结果非常稳定地翻车。原因有三个:

第一,上下文长度和注意力是有限的。你把三百道菜的做法、价格、库存全塞进提示词,模型在回答"推荐个清淡的"时,很可能被无关信息干扰,推荐出一道重油重辣的菜。这不是模型笨,是信息过载。

第二,业务规则会变,提示词改起来要命。今天搞活动满减,明天换菜单,你不可能每次都去改那段几千字的提示词,改完还要重新测一遍,成本极高。

第三,无法保证输出格式。你希望它返回JSON,它偏要给你写一段散文,下游系统根本没法解析。

所以九添菜菜这个项目,从一开始就没有走"大提示词"路线,而是采用了**"意图识别 + 工具调用 + 状态管理"**的三层结构。这也是目前主流智能体框架(无论是LangChain、LangGraph还是其他)的通用思路。

2.2 三层结构各自负责什么

第一层:意图识别与路由。用户说一句话,先判断他想干什么。是问菜品推荐?是查营业时间?是投诉?还是闲聊?这一层通常用一个轻量模型或规则+小模型组合来完成,目的是快速分流,避免所有请求都走最贵的模型。

第二层:工具调用与执行。一旦确定意图,就调用对应的工具函数。比如"推荐菜品"这个意图,会触发一个recommend_dishes函数,它接收人数、预算、口味偏好等参数,去查数据库或调用内部API,返回候选列表。注意,这里的数据查询是确定性的,不依赖模型"记忆",所以结果可靠。

第三层:状态管理与多轮对话。用户不会一次把话说全。他可能先说"六个人",你问预算,他说"三百左右",你推荐完,他又说"有没有不辣的"。这就需要维护一个对话状态,记住已经收集到的信息,避免重复询问。LangGraph这类框架的StateGraph就是干这个的。

我用一个简化的流程来说明这三层怎么串起来:

# 伪代码示意,非完整可运行代码 def handle_user_input(user_input, state): intent = classify_intent(user_input) # 第一层 if intent == "recommend": params = extract_params(user_input, state) # 从对话中抽取参数 if not params.get("budget"): return ask_for_budget(state) # 信息不全,追问 result = recommend_dishes(params) # 第二层,调用工具 state["last_recommendation"] = result return format_response(result) # 第三层,结合状态生成回复 elif intent == "hours": return query_business_hours() # ...其他意图

这段伪代码看起来简单,但每一行背后都有讲究。比如classify_intent,你是用规则匹配还是用模型?规则快但覆盖不全,模型准但慢且贵。我的经验是:高频、边界清晰的意图用规则,长尾、表达多样的意图用模型。九添菜菜里,"营业时间""订座电话"这种就用关键词匹配,"推荐""搭配""忌口"这种就用模型分类。

2.3 工具函数的设计原则:别让模型做它不擅长的事

这是我想重点强调的一点。很多新手会把"计算总价""判断库存"这种事交给模型,结果就是它算错、它幻觉。凡是能用代码确定性完成的,绝不要交给模型。

九添菜菜里有一个典型场景:顾客点了一桌菜,要算总价并应用满减。正确做法是写一个calculate_total(items, promotions)函数,用纯代码算,模型只负责把顾客的话解析成items列表。这样算出来的价格永远准确,而且可以单元测试。

工具函数的另一个原则是参数要明确、返回值要结构化。不要设计一个do_something(query)这种模糊接口,而应该是search_menu(category, taste, price_range)这种参数清晰的函数。参数越明确,模型越容易正确调用,出错也越容易定位。

3. 从零搭一个九添菜菜:环境、选型与第一个能跑的版本

3.1 模型选型:不是越贵越好

做智能体,模型选型是第一个岔路口。我的建议是分层使用:

任务类型推荐模型级别理由
意图分类小模型/本地模型任务简单,高频调用,成本敏感
参数抽取中等模型需要一定理解能力,但不需要太强
复杂推理/生成大模型涉及多步推理、创意生成时才用
格式化输出中等模型+约束解码需要严格JSON,可用结构化输出能力

九添菜菜项目里,意图分类我用的是一个7B级别的本地模型,跑在一张消费级显卡上,延迟低、成本几乎为零。参数抽取和最终生成用的是云端大模型API。这样整体成本能压到纯用大模型的十分之一左右。

提示:不要一上来就追求"最强模型"。先用小模型跑通流程,发现哪里效果不行,再针对性换大模型。这样你能清楚知道瓶颈在哪,而不是盲目堆算力。

3.2 框架选择:LangGraph还是自己写

现在智能体框架很多,LangChain、LangGraph、AutoGen、Dify等等。我的看法是:如果你要快速验证,用Dify这类可视化平台;如果你要深度定制和上线,用LangGraph或自己写状态机。

九添菜菜用的是LangGraph的思路,但核心状态管理是自己写的。原因是我需要精确控制每一步的流转,而且不想被框架的抽象层挡住调试视线。自己写状态机的好处是,出问题时你能一眼看到是哪个状态、哪个转移条件出了错。

一个最简的状态定义大概长这样:

class AgentState: def __init__(self): self.messages = [] # 对话历史 self.intent = None # 当前意图 self.slots = {} # 已收集的参数槽位 self.pending_question = None # 待追问的问题 self.tool_results = [] # 工具调用结果

这个结构看着朴素,但它把"对话"和"任务"分开了。messages是给人看的,slots是给机器用的。很多项目失败就是因为把两者混在一起,导致状态混乱。

3.3 第一个能跑的版本:只做一件事

新手最容易犯的错是贪多。一上来就想做全功能,结果哪个都不完整。我的建议是:第一个版本只做一个意图、一个工具、一条路径。

九添菜菜的第一个可运行版本,只做"根据人数推荐菜品"这一件事。流程是:

  1. 用户说"我们四个人吃饭"
  2. 意图识别为recommend
  3. 参数抽取得到people=4
  4. 追问预算和口味
  5. 用户回答后,调用recommend_dishes
  6. 返回推荐结果

就这六步,跑通它,你就理解了智能体的核心循环。之后再往上加意图、加工具、加多轮状态,都是在这个骨架上扩展。

我实测下来,这个最小版本大概两百行代码就能搞定,但它是后面所有复杂功能的基础。不要跳过这一步直接抄复杂项目,你会看不懂每一行为什么这么写。

4. 让九添菜菜真正"能用":参数抽取、追问策略与容错

4.1 参数抽取:从自然语言到结构化数据的惊险一跃

用户说"我们六个人,想吃得清淡点,预算别超过四百",你要抽取出{people: 6, taste: "清淡", budget: 400}。这一步做不好,后面全错。

我的做法是用模型做抽取,但用Schema约束输出。具体来说,定义一个JSON Schema,告诉模型必须按这个格式返回。现在很多模型API都支持结构化输出(structured output),能大幅降低格式错误率。

{ "people": "integer or null", "taste": "string or null", "budget": "number or null", "avoid": "array of strings" }

注意,所有字段都允许为null。因为用户可能只说了一部分信息,你不能强迫模型编造。抽不到的,就留空,后面用追问补上。

这里有个坑:中文数字和模糊表达。用户说"六个人""俩人""三四位",模型有时候会抽错。我的处理是,在抽取后加一层归一化:把"俩"转成2,"三四"转成3(取最小值,保守估计),"六"转成6。这层归一化用规则做,比让模型做更可靠。

4.2 追问策略:别像查户口一样问

信息不全就要追问,但追问的方式直接影响体验。我见过一些智能体,像查户口一样:"请问几位?""请问预算多少?""请问口味偏好?"——用户烦都烦死了。

九添菜菜的追问策略是合并追问 + 智能默认:

  • 如果缺多个信息,一次性问:"方便告诉我大概几位、预算多少吗?口味有偏好吗?"
  • 如果某个信息可以从上下文推断,就不问。比如用户说"就我和我老婆",那people直接推断为2。
  • 如果某个信息不影响核心结果,可以用默认值。比如口味没提,默认"不限",而不是非要问出来。

这个策略的实现,是在状态机里维护一个missing_slots列表,每次生成回复前检查,如果列表非空,就生成一个合并的追问。追问的措辞也可以预先写好模板,避免每次让模型现编。

4.3 容错:模型会犯错,系统不能崩

智能体上线后,你会遇到各种意外:模型返回了非法JSON、工具调用超时、用户输入了完全无关的内容。这些都必须有兜底。

我的容错清单:

  • JSON解析失败:重试一次,如果还失败,降级到规则解析或返回友好提示。
  • 工具调用超时:设置超时时间(比如3秒),超时后返回"稍等,我查一下"并异步重试,或者直接给一个保守的默认结果。
  • 意图识别置信度低:如果模型对意图的判断置信度低于阈值,不要硬猜,直接问"您是想问菜品推荐,还是其他问题?"
  • 用户输入无关内容:识别为chitchat或unknown,用预设话术引导回正题。

这些兜底逻辑,代码量不大,但能极大提升系统的"稳"。我踩过的最大坑就是没做超时处理,结果某个内部API挂了,整个智能体卡死,用户等了一分钟没反应直接关掉。

5. 评测与迭代:怎么知道九添菜菜是真的变好了

5.1 没有评测集的智能体项目都是耍流氓

这是我最想对同行说的一句话。很多人做完智能体,自己试几句觉得"还行",就上线了。结果真实用户一用,各种奇葩输入,效果惨不忍睹。

正确做法是:在开发早期就建立评测集。九添菜菜的评测集包含三类样本:

  • 正常样本:标准表达,比如"六个人,预算三百,推荐几个菜"。
  • 边界样本:模糊表达、多意图混合、信息缺失,比如"随便来点"、"上次那个菜再来一份"。
  • 对抗样本:故意刁难,比如"你们这有没有不存在的菜"、"帮我算一下一加一"。

每类样本至少几十条,覆盖主要意图和工具。每次改动提示词、换模型、加工具,都跑一遍评测集,看通过率变化。

5.2 评测指标:不只看"对不对"

智能体的评测比传统分类任务复杂,因为它是多轮的。我用的指标有:

指标含义目标
意图准确率意图识别正确的比例>95%
参数抽取F1抽取参数的准确率和召回率>90%
任务完成率多轮对话后成功完成任务的比率>85%
平均轮次完成任务平均需要几轮对话越少越好
幻觉率编造不存在信息的比例<2%

其中任务完成率是最重要的,因为它反映端到端体验。一个意图识别98%但任务完成率只有60%的系统,是不合格的。

5.3 迭代的优先级:先修高频错误

拿到评测结果后,不要眉毛胡子一把抓。我的做法是按错误频率排序,先修出现最多的那类错误。

比如九添菜菜早期,最高频的错误是"预算抽取错误",占了所有错误的40%。那我就集中精力优化预算抽取:加归一化规则、加few-shot示例、换更强的抽取模型。修完这一类,整体通过率直接涨了15个百分点。

这种"抓大放小"的迭代方式,比均匀地优化每个环节效率高得多。因为长尾错误可能只占2%,你花大力气修完,整体提升也就2%。

6. 上线之后才是真正的开始:监控、反馈与持续优化

6.1 日志要记什么

智能体上线后,日志是你的眼睛。但日志不是记得越多越好,而是要记能帮你定位问题的关键信息。九添菜菜的日志包含:

  • 用户原始输入(脱敏后)
  • 识别出的意图和置信度
  • 抽取的参数
  • 调用的工具和参数
  • 工具返回结果(截断)
  • 最终回复
  • 耗时(分阶段)

有了这些,当用户投诉"它答非所问"时,你能快速定位是意图错了、参数错了、还是工具返回错了。

6.2 用户反馈的收集与利用

显式反馈(点赞点踩)要收集,但更宝贵的是隐式反馈。比如:

  • 用户重复问同一个问题 → 说明第一次没答好
  • 用户直接关闭对话 → 可能是不满意
  • 用户手动纠正 → 说明系统理解错了

这些信号比点赞点踩更真实。九添菜菜里,我会把"用户连续两次表达同一意图"标记为一次潜在失败,纳入每周的复盘。

6.3 一个真实的迭代案例

上线两周后,我们发现"推荐菜品"这个意图的完成率只有72%,明显低于其他意图。查日志发现,问题出在多轮对话中的指代消解。

用户第一轮说"推荐几个菜",系统推荐了A、B、C。用户第二轮说"第一个换成不辣的"。系统这时候懵了——"第一个"指什么?它没有记住上一轮的推荐列表。

修复方案是在状态里显式保存last_recommendation,并在参数抽取时把上一轮的推荐列表作为上下文传进去。改完之后,这个意图的完成率涨到了89%。

这个案例说明:多轮对话的难点不在单轮理解,而在跨轮的状态维护。很多智能体Demo很惊艳,一进入多轮就露馅,就是因为状态没管好。

7. 关于智能体开发,我踩过的最深的三个坑

7.1 坑一:把模型当数据库用

早期我图省事,把菜单信息直接写进提示词,让模型"记住"。结果模型经常记混价格,或者推荐已经下架的菜。后来改成工具查询,问题立刻消失。

教训:模型是推理引擎,不是存储引擎。所有事实性数据都应该放在外部,通过工具查询。

7.2 坑二:忽视冷启动时的"空状态"

用户第一次进来,没有任何历史信息。这时候如果状态机设计得不好,很容易出现"系统不知道该问什么"或者"重复问已经问过的"。我的做法是给每个意图定义一个最小信息集,进入意图时先检查这个集合,缺什么问什么,问过的绝不重复问。

7.3 坑三:过度依赖单一模型

有段时间我所有环节都用同一个大模型,结果那个模型API一抖动,整个系统就不可用。后来做了分层和降级:意图分类用本地小模型,抽取用中等模型,生成用大模型。任何一层出问题,都有降级方案。系统的可用性从"看API脸色"变成了"基本稳定"。

8. 如果你现在要开始做自己的智能体

最后分享一点个人体会。智能体开发这件事,技术门槛其实没有想象中高,真正的门槛在于对业务的理解和对细节的打磨。九添菜菜这个项目,代码量不算大,但每一处追问策略、每一个容错分支、每一条评测样本,都是反复推敲出来的。

如果你现在要开始,我的建议是:找一个你真正熟悉的场景,哪怕很小,比如"帮同事订会议室"或者"整理每周工作汇报"。先用最小版本跑通"意图-工具-回复"的循环,然后建评测集,然后一轮一轮迭代。不要一上来就追求大而全,也不要迷信某个框架或某个模型。

真正让智能体好用的,从来不是模型有多强,而是你有没有把它的能力,恰当地约束在一个清晰的流程里。这个道理,我在九添菜菜项目里体会得特别深。

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

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

立即咨询