Skip to content

模型与模板

🎯 学习目标

  • 使用 ChatOpenAI / ChatOllama 等 ChatModel 替代 legacy LLM 接口
  • 编写 ChatPromptTemplate、FewShotPromptTemplate
  • 配置 InMemoryCache / RedisCache 并理解 Agent 场景的缓存陷阱

引言

ChatModel 以 messages 数组为输入,与 OpenAI Chat Completions 对齐。Prompt Template 把变量注入 System/Human/AI 角色;缓存则在开发阶段大幅降本。

章节正文

第 1 步:ChatModel 与参数绑定

python
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0.2,
    max_tokens=1024,
    timeout=30,
)
# 预绑定参数,链内复用
llm_creative = llm.bind(temperature=0.9)

# 本地 Ollama
from langchain_ollama import ChatOllama
local = ChatOllama(model="qwen2.5:7b", temperature=0)

invoke 传入 messages 或 Template 输出;stream 逐 chunk 返回,与 SSE 流式输出 配合前端展示。

第 2 步:ChatPromptTemplate 与 MessagesPlaceholder

python
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是{role}。当前日期:{today}"),
    MessagesPlaceholder("history"),  # 多轮对话槽位
    ("human", "{input}"),
])

messages = prompt.format_messages(
    role="客服助手",
    today="2026-06-25",
    history=[("human", "你好"), ("ai", "您好,有什么可以帮您?")],
    input="如何退款?",
)
resp = llm.invoke(messages)

模板应版本化管理(Git 或配置中心),与 Eval 集联动(7.1)。

第 3 步:Few-shot 示例注入

python
from langchain_core.prompts import FewShotChatMessagePromptTemplate

examples = [
    {"input": "太烂了", "output": "负面"},
    {"input": "还行吧", "output": "中性"},
]
example_prompt = ChatPromptTemplate.from_messages([
    ("human", "{input}"),
    ("ai", "{output}"),
])
few_shot = FewShotChatMessagePromptTemplate(
    example_prompt=example_prompt,
    examples=examples,
)
final_prompt = ChatPromptTemplate.from_messages([
    ("system", "对评论做情感分类,只输出:正面/负面/中性"),
    few_shot,
    ("human", "{input}"),
])

少样本适合格式稳定的小任务;示例过多会占用 Token,需与窗口预算平衡。

第 4 步:LLM 缓存

python
from langchain_core.globals import set_llm_cache
from langchain_core.caches import InMemoryCache
# from langchain_community.cache import RedisCache

set_llm_cache(InMemoryCache())

# 相同 prompt + 相同 model 参数 → 命中缓存,不再请求 API
chain = prompt | llm | StrOutputParser()
chain.invoke({"input": "hello"})  # 第一次:API
chain.invoke({"input": "hello"})  # 第二次:缓存

注意:Agent 场景上下文不断变化,缓存 key 几乎不会命中;RAG 检索结果变化时也不要缓存最终答案。开发调试可开,生产对静态子链(如分类路由) selectively 开启。

动手练习

  1. 实现带 history 槽位的客服 Prompt,模拟两轮 invoke
  2. 为情感分类任务写 3 个 few-shot 示例并测试边界评论
  3. 对比开/关 InMemoryCache 时同一问题的 API 调用次数(可配合 LangSmith 或打印)

常见问题

Q:LLM 和 ChatModel 还能混用吗?

legacy LLM 接口(字符串进字符串出)已不推荐;新代码统一 ChatModel + ChatPromptTemplate。

本节小结

ChatModel 统一多厂商消息接口;ChatPromptTemplate 与 Few-shot 模板化 Prompt;MessagesPlaceholder 支持多轮;缓存适合开发与子链,Agent 全链路慎用。