实战:用 Dify 复刻烹饪助手

实战锚点 · cooking-app:用 Dify 重做一遍烹饪问答,并回答关键问题——什么时候必须离开平台写代码。

Dify 篇收官战:把 cooking-app 的 AI 问答完整复刻到 Dify 上,然后逐条对照"平台版 vs 代码版"——平台边界在哪、什么时候必须写代码,这一章给出可复用的判断清单。

目标拆解

cooking-app(Flutter + NestJS)的 AI 能力现在有三块:

  1. 烹饪问答(裸 SDK,ai.service.ts,第 2 章读过)
  2. 个性化推荐(结合用户口味偏好——数据在 app 自己的库里)
  3. (计划中)菜谱解析与营养计算——结构化任务

用 Dify 复刻 = 把 1 做成主菜,2/3 当作边界探针。

复刻主体:问答(30 分钟)

Step 1 · 聊天助手 + system prompt:把 buildSystemPrompt() 全文搬进编排(第 2 章已搬过,这次加上 few-shot 问答示例,回答质量立刻上一个档次)。

Step 2 · 挂知识库:把 cooking-app 里的菜谱数据(假设 50 道菜)整理成 md,按第 4 章的方法建知识库、跑召回测试("鸡胸肉""快手菜""减脂晚餐"三组问法必须全命中)。挂到应用上下文。

Step 3 · API 化:发布 → 拿 chat-messages API。Flutter 端把原来调 NestJS /ai/chat 的代码改成调 Dify(SSE 流式渲染顺手加上——移动端流式 UI 是个体力活,也是前端价值所在)。

完成。此刻值得停下来感受一下:裸代码版花了一周的东西,Dify 上是半小时,而且自带了知识库、记忆配置、发布页和运营面板。这就是平台层的真实价值,不用讳言。

边界探针一:个性化推荐(平台开始吃力)

需求:回答要结合用户口味(不吃辣、低碳水偏好——数据在 app 的 users 表里)。

平台内尝试:Dify 有"会话变量",可以每轮从客户端传 user_profile 进来拼 prompt。

【用户偏好】{{user_profile}}

能跑。但注意代价:用户数据每次从客户端明文过一遍第三方平台;偏好更新要客户端主动传;想基于历史行为自动推断?平台摸不到你的数据库。凑合能用的边缘。

边界探针二:菜谱解析 + 营养计算(平台放弃)

需求:用户拍一张菜谱照片 → 提取食材 → 按份量精确计算卡路里 → 和用户目标对比。

  • 视觉理解:Dify 支持多模态模型,OK
  • 提取食材:LLM 节点 + JSON mode,OK
  • 精确计算卡路里:LLM 算数不可靠(第 2 章讲过),必须查营养数据库 + 代码计算
  • 平台做法:HTTP 节点调你后端的计算接口 → 每次请求出平台、进你的服务器、再回平台——业务逻辑已经被劈成两半,画布成了胶水,调试痛苦开始超过收益

到这里,判断很清楚:该写代码了。

什么时候离开平台:判断清单

信号说明
🟢 留在平台标准问答/知识库/简单流程(本章 Step1-3)/To B 快速交付 demo
🟡 平台+代码混搭需要碰你的数据库(HTTP 节点少量够用);流程中个别精确计算
🔴 全代码复杂状态跨步骤流转;动态流程结构;核心数据不能出系统;性能/成本需要精细优化;深度嵌入现有工程体系(CI、测试、监控)

一个可迁移的判断原则:当你在平台里绕着"做不到"打补丁的时间,超过直接写代码的时间,就该切换了。

cooking-app 的结论:问答留 Dify(降本)或迁 LangChain(统一技术栈),个性化+营养计算必须进自己的 NestJS——这个"哪些留平台哪些写代码"的拆分本身就是架构能力,面试里讲出来非常加分。

Dify 篇收官自查

  • 会建三种应用(助手/Chatflow/Workflow)并知道选哪个
  • 知识库:会建、会调分段、会跑召回测试
  • 画布:会用 LLM 分类 + 条件分支 + HTTP 节点 + 变量引用
  • 会把应用 API 化并接进自己的前端(流式)
  • 能对着清单说出"留平台/混搭/全代码"的判断依据

下一篇预告:拿回控制权

Dify 篇里每次"这也要绕",都是玻璃天花板。下一篇开始写代码——用 LangChain.js 把 cooking-app 的 AI 服务从裸 SDK 重构成框架级实现:模型 IO、工具调用、MCP、记忆、RAG,一层层把平台替你做的事全部收回到自己手里。

→ 下一章:LangChain.js 第一步:模型 IO 与流式