LangChain LangGraph
Module 1 Module 2 Module 3
Module 1 · 基础能力
1 1.1a 基础模型
2 1.1b Prompting
3 1.2a Tools
4 1.2b Web Search
5 1.3 Memory
6 1.4 Multimodal
7 1.5 Personal Chef
SUM Module Summary
HomeLangChainModule 1 · 基础能力1.5 Personal Chef
📓 Notebook 📖 Explained
LANGCHAIN MODULE 1 · LESSON 1.5 · 实战项目

实战项目:个人厨师 Agent
Web搜索 + 记忆 + System Prompt 综合应用

Module 1 的收官项目——把所有技能整合在一起:用 Tavily 搜索菜谱、用 InMemorySaver 记住用户食材、用 System Prompt 定义厨师角色,构建一个真实可用的个人厨师 Agent。

1 项目目标:整合 Module 1 所有能力

个人厨师 Agent 是 Module 1 的综合实战项目,它集成了前面所有课程的核心能力:

🧠
模型初始化(1.1a)
用 init_chat_model 初始化 DeepSeek
💬
System Prompt(1.1b)
定义厨师角色和行为边界
🔍
Web 搜索(1.2b)
Tavily 搜索实时菜谱
💾
记忆(1.3)
InMemorySaver 记住对话历史
为什么这个项目有价值

个人厨师 Agent 是一个真实可用的应用:用户告诉 Agent 家里有什么食材,Agent 搜索对应的菜谱,在后续对话中记住用户的食材,可以持续提供建议、询问具体做法。这正是 LangChain Agent 的典型使用场景——结合工具调用、记忆和角色设定。

2 完整代码:5 个关键组件的组合

from dotenv import load_dotenv
load_dotenv()

import os
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
from langchain.messages import HumanMessage
from langchain.tools import tool
from langgraph.checkpoint.memory import InMemorySaver
from tavily import TavilyClient

# ────────────────────────────────────
# 组件 1:模型工厂函数
# ────────────────────────────────────
def deepseek_model(**kwargs):
    return init_chat_model(
        model="deepseek-chat",
        model_provider="openai",
        api_key=os.environ["DEEPSEEK_API_KEY"],
        base_url="https://api.deepseek.com",
        max_tokens=1000,
        **kwargs
    )

# ────────────────────────────────────
# 组件 2:Web 搜索工具
# ────────────────────────────────────
tavily_client = TavilyClient()

@tool
def web_search(query: str) -> dict:
    """Search the web for information"""
    return tavily_client.search(query)

# ────────────────────────────────────
# 组件 3:System Prompt(厨师角色定义)
# ────────────────────────────────────
system_prompt = """

You are a personal chef. The user will give you a list of ingredients they have left over in their house.

Using the web search tool, search the web for recipes that can be made with the ingredients they have.

Return recipe suggestions and eventually the recipe instructions to the user, if requested.

"""

# ────────────────────────────────────
# 组件 4 + 5:Agent = 模型 + 工具 + System Prompt + 记忆
# ────────────────────────────────────
agent = create_agent(
    model=deepseek_model(),
    tools=[web_search],
    system_prompt=system_prompt,
    checkpointer=InMemorySaver()
)

3 System Prompt:定义厨师 Agent 的行为

System Prompt 是这个 Agent 的"灵魂"——它定义了 Agent 的角色、能力边界和响应方式:

system_prompt = """

You are a personal chef. The user will give you a list of ingredients they have left over in their house.

Using the web search tool, search the web for recipes that can be made with the ingredients they have.

Return recipe suggestions and eventually the recipe instructions to the user, if requested.

"""

这个 prompt 做了三件事:

  1. 定义角色:"You are a personal chef"——模型知道自己是谁,行为风格会有所不同
  2. 明确工具使用策略:"Using the web search tool, search the web..."——显式指示模型使用搜索工具,而不是凭 LLM 知识瞎编菜谱
  3. 定义响应格式:"Return recipe suggestions and eventually the recipe instructions..."——先给建议,用户要求后再给详细步骤
为什么要显式指示使用工具?

LLM 有大量烹饪知识,不指示使用工具时,它可能直接凭自己的知识回答——这对于菜谱来说看起来合理,但可能与用户现有食材不匹配,或者给出不准确的做法。通过 system prompt 明确要求"search the web",确保 Agent 总是基于搜索结果给出建议,而不是凭空生成。

4 web_search 工具:实时搜索食谱

这里的 web_search 工具比之前的稍有不同——使用了 @tool 的简化写法(不指定 name,自动用函数名),并且 description 来自 docstring:

@tool                    # 简化写法:name 自动为 "web_search"
def web_search(query: str) -> dict:
    """Search the web for information"""   # docstring 作为 description
    return tavily_client.search(query)
@tool 的两种写法对比

显式写法(推荐):@tool("web_search", description="Search the web for...")
简化写法(本例):@tool,name = 函数名,description = docstring

简化写法更简洁,但要确保函数名清晰(web_search 而不是 search)、docstring 描述充分。

5 多轮对话演示:记住食材,持续对话

config = {"configurable": {"thread_id": "1"}}

# 轮次 1:告诉 Agent 有什么食材
response = agent.invoke(
    {"messages": [HumanMessage(content="I have some leftover chicken and rice. What can I make?")]},
    config
)
print(response['messages'][-1].content)
厨师 Agent 响应(轮次 1)
Based on my search, here are some delicious recipes you can make with chicken and rice:

1. **Chicken Fried Rice** — A classic dish using day-old rice, diced chicken, eggs, soy sauce, and vegetables. Quick to make in under 20 minutes.

2. **Chicken and Rice Soup** — A comforting one-pot meal. Simmer chicken pieces with rice, vegetables, and broth for a warming soup.

3. **Chicken Rice Casserole** — Mix chicken, rice, cream of mushroom soup, and bake for 45 minutes. Great for meal prep!

Would you like the detailed recipe instructions for any of these?

Agent 调用了 web_search,搜索"chicken and rice recipes",基于搜索结果给出了 3 个建议,并邀请用户选择一个要详细步骤的菜谱。

轮次 2:询问具体做法(利用记忆)

# 轮次 2:用户要鸡肉炒饭的做法(Agent 记住了上一轮的食材)
response2 = agent.invoke(
    {"messages": [HumanMessage(content="Can you give me the detailed recipe for chicken fried rice?")]},
    config
)
print(response2['messages'][-1].content)
厨师 Agent 响应(轮次 2)
Here's the detailed recipe for **Chicken Fried Rice**:

**Ingredients:**
- 2 cups cooked rice (day-old works best)
- 1 cup diced chicken (cooked)
- 2 eggs, beaten
- 2 tbsp soy sauce
- 1 tbsp sesame oil
- 1 cup mixed vegetables

**Instructions:**
1. Heat oil in a wok over high heat...
...
记忆在这里的价值

在轮次 2 里,用户直接说"give me the detailed recipe for chicken fried rice",没有重复提到"chicken and rice"。Agent 之所以能理解这个请求并给出正确回应,是因为InMemorySaver 保存了轮次 1 的对话历史——Agent 知道之前讨论了哪几个菜谱选项。

6 Agent 执行流程深度解析

当用户说"I have some leftover chicken and rice. What can I make?"时,Agent 内部的完整执行流程:

7 Module 1 知识全景回顾与下一步

至此,Module 1 的 7 个 Lesson 全部完成。以下是完整的知识全景:

LangChain Module 1 完整知识图谱
1.1a 基础模型
  • init_chat_model — 统一初始化
  • create_agent — 构建 Agent
  • invoke / stream — 调用方式
1.1b 提示工程
  • • Basic → Few-shot → Structured Prompt
  • response_format=Pydantic — 结构化输出
  • structured_response — 取 Pydantic 对象
1.2a 工具
  • @tool 装饰器 — 定义工具
  • tools=[...] — 绑定到 Agent
  • • ReAct 循环:推理 → 调用 → 推理
1.2b Web 搜索
  • • Tavily — 专为 AI 优化的搜索 API
  • • 打破 LLM 知识截止限制
  • • 实时 RAG:检索 + 生成
1.3 记忆
  • InMemorySaver — 内存 Checkpointer
  • thread_id — 区分对话上下文
  • • 每次 invoke 只传当前新消息
1.4 多模态
  • • content 列表:文本 / 图片 / 音频
  • • 图片:base64 → Data URI
  • • 模型支持情况各异,注意选型
Module 1 → Module 2 的衔接

Module 1 建立了 LangChain Agent 的完整基础:模型调用、提示工程、工具调用、记忆。Module 2 将深入探索更复杂的 Agent 设计模式——多 Agent 协作、状态管理、更复杂的记忆策略等。个人厨师 Agent 是一个很好的起点,真实项目的 Agent 就是这样一步步构建起来的。