LangChain 实战|AI 私厨 Agent:拍照识别冰箱食材,自动生成食谱推荐

    |     2026年8月22日   |   AI大模型应用, LangChain框架   |     0 条评论   |    38

上篇你给 Agent 装上了记忆——thread_id 能续聊,爆窗还有三种策略。零件齐了:Models、Messages(含看图)、Tools、Memory。这篇按导图做一次入门实战:AI 私厨——拍照认食材,再推荐食谱。


小明接到「看冰箱做菜」需求

产品经理丢来一句话(几乎就是导图原文):

AI私厨:基于 LangChain + 多模态。
用户拍冰箱/厨房照片 → AI 识别食材 → 按食材搜食谱推荐。

小明零件都会:看图 Messages、@tool、外挂记忆、create_agent。一拼项目却又散了——配置写在 main 里,工具和记忆各拷一份,演示脚本和排障日志缠在一起。

他去找老张:”业务怎么走?代码怎么拆,才不像练手时那样焊死?”

老张说:”业务跟导图;骨架:config → llm → tools/ → memory → agent → main。私厨只是换工具与输入形态(图文 Messages)。”


什么是 AI 私厨(需求 + 整合范式)

用户拍照 / 上传冰箱图
    ↓
多模态模型:认出食材列表(Messages 图文)
    ↓
工具:按食材检索食谱(模拟或真实 API)
    ↓
记忆:记住忌口、上次推荐,支持追问「换一个素的」
    ↓
(可选)LangSmith:看清每一步调用轨迹

“实现思路四层:

  1. 感知 —— HumanMessage content 挂图片(上篇 Messages)
  2. 行动 —— search_recipes(ingredients=...) 一类 @tool
  3. 记忆 —— 对话历史含工具中间消息(ConversationMemory)
  4. 编排 —— create_agent + 清晰 system_prompt

验收范式:--demo 多轮可跑通;私厨验收:一张食材图 → 推荐列表(可录屏)。”

步骤(导图) 落点
2.1 配置 .env config.py
2.2~2.3 依赖 / 加载配置 requirements + load_dotenv
2.4 定义工具 tools/ 分包
2.5 初始化模型 llm.get_chat_model(需视觉能力时换多模态模型名)
2.6 记忆管理 ConversationMemory 或 checkpointer
2.7 初始化 Agent create_agent + Assistant
2.8 测试 main.py --demo
3 LangSmith 环境变量打开追踪(可观测,可选)

代码拆解:先骨架,再换成私厨零件

1. 配置:环境只有一处真相

config.py:

from dotenv import load_dotenv
import os

load_dotenv()

API_KEY = os.environ["OPENAI_API_KEY"]
BASE_URL = os.environ.get("OPENAI_BASE_URL")
MODEL_NAME = os.environ.get("OPENAI_MODEL", "qwen-plus")
TEMPERATURE = 0

“私厨同样先保证 .env 通。若看图,把 OPENAI_MODEL 换成网关支持的视觉模型;文本工具链可仍用普通 Chat 模型——按你的供应商文档选。”

2. 工具:从 mock_search 到「搜食谱」

已有分包与模拟搜索:

# tools/search.py
@tool
def mock_search(query: str) -> str:
  """模拟搜索非天气、非算术类问题。"""
  return f"[模拟搜索] {query} → LangChain 用于编排大模型应用。"

tools/__init__.py 汇总:

TOOLS = [get_weather, calculator, mock_search]

“私厨把业务工具换成食谱检索即可,写法不变——注释写清何时调用:”

@tool
def search_recipes(ingredients: str) -> str:
  """根据食材关键词检索食谱。ingredients 用逗号分隔,如「鸡蛋,西红柿」。"""
  # 教学可用模拟表;接真实 API 时只改函数体
  catalog = {
    "鸡蛋,西红柿": "1) 西红柿炒蛋 2) 蛋炒饭加丁",
    "土豆,排骨": "1) 土豆烧排骨 2) 排骨汤",
  }
  key = ingredients.replace(",", ",").replace(" ", "")
  return catalog.get(key, f"[模拟食谱] 含「{ingredients}」的家常做法 2~3 道(假数据)")

“天气/计算器可删可留;私厨最小集:search_recipes(+ 可选忌口查询)。扩展口诀仍是:新文件 → 写入 TOOLS。”

3. 记忆:保留工具中间消息

memory.py:

class ConversationMemory:
  def add_user(self, text: str) -> None:
    self._messages.append(HumanMessage(content=text))

  def replace_all(self, messages: list[BaseMessage]) -> None:
    self._messages = list(messages)

  def as_messages(self) -> list[BaseMessage]:
    return list(self._messages)

“注意 replace_all(result['messages']):Agent 跑完后整段轨迹(含 ToolMessage)写回记忆,追问「换个少油的」才接得上。这比只存最后一句回答靠谱。”

4. Agent + Assistant:整合心脏

agent.py:

SYSTEM = (
  "你是 CLI 数字助理。天气→get_weather,算术→calculator,其它资料→mock_search。"
  "回答简洁;能引用对话上文中的称呼与偏好。"
)


def build_agent():
  return create_agent(get_chat_model(), tools=TOOLS, system_prompt=SYSTEM)


class Assistant:
  def __init__(self) -> None:
    self.memory = ConversationMemory()
    self.agent = build_agent()

  def chat(self, user_text: str) -> str:
    self.memory.add_user(user_text)
    result = self.agent.invoke({"messages": self.memory.as_messages()})
    self.memory.replace_all(result["messages"])
    last = self.memory.as_messages()[-1]
    return getattr(last, "content", str(last)) or ""

“私厨只改三处:

  1. SYSTEM →「你是私厨助手:先识别/确认食材,再必须调用 search_recipes,不要编造菜谱细节」
  2. TOOLS → 食谱工具列表
  3. chat 增加图文入口:用户丢图时,add_user 改为追加带 image_url 的 HumanMessage(Messages 篇)

文本追问仍走字符串 HumanMessage——同一条记忆链。”

图文输入示意(拼在 Assistant 上,协议来自 Messages 篇):

from langchain_core.messages import HumanMessage

def add_user_with_image(self, text: str, image_url: str) -> None:
  self.memory._messages.append(
    HumanMessage(
      content=[
        {"type": "text", "text": text},
        {"type": "image_url", "image_url": {"url": image_url}},
      ]
    )
  )

5. main:Demo 与 CLI

main.py 的 --demo 节奏可直接复用:

def run_demo() -> None:
  bot = Assistant()
  for t in ["我叫小明", "杭州天气怎么样?", "按刚才气温数字,帮我算它加 5", "我叫什么?"]:
    print("你:", t)
    print("助理:", bot.chat(t))

“私厨 demo 换成:

1) 上传/指定冰箱图 URL → 识别食材并推荐
2) 「我有点蒜」→ 记忆续聊,改推荐
3) /clear → 新会话

LangSmith(导图第 3 步):按官网给项目配 LANGCHAIN_TRACING_V2 / API Key,在控制台点开本次 invoke,核对是否先看图、再调 search_recipes。可选,但排障极香。”


总结

老张说:”第八篇只办一件事——把前七篇零件装进一个可演示的私厨。”

“三个核心理解:

  1. 业务闭环 —— 看图认食材 → 工具搜食谱 → 记忆支持追问
  2. 工程骨架 —— config / llm / tools / memory / agent / main
  3. 可观测可选 —— LangSmith 核对「是否真调了工具」”

LangChain 支线进度:

… → Memory
    ↓
AI 私厨实战(本篇:整合演示)
    ↓
Runtime(State / Store / Context)→ Middleware → …

小明说:”私厨能演示了,但 visit_count、用户档案、跨会话偏好还没分清——那是 Runtime 的事。”

“对。下一篇:Runtime:State / Store / Context。”

入门实战不是堆新 API,而是用干净骨架把多模态、工具、记忆跑成一条用户故事。教你怎么拆文件,私厨教你为什么值得拆。

转载请注明来源:LangChain 实战|AI 私厨 Agent:拍照识别冰箱食材,自动生成食谱推荐
本文链接地址:https://ai.zhousir.top/?p=3860
回复 取消