4.Message与提示词模板2

一、 content_blocks 的使用 (实现多模态输入与输出)

content_blocks 在 LangChain 中不仅在 【输入端】 扮演多模态数据(文本、图片等)自由组装 and 排版的角色,同时在 【输出端】 扮演了承载大模型返回的所有结构化"块"(如普通文本块 text、深度思考/思维链块 reasoning、工具调用块等)的角色。它是双向起作用的。

他起的核心作用是可以把图片,音频,视频,和文字混合着放,去更好的表达我们的想法

1. 输入端:多模态自由混排 (多模态提示词模板)

(1) 核心价值

  • 强兼容性 :统一使用 content_blocks,可完美兼容 OpenAI、Claude、Gemini 等不同平台的多模态接口,避免使用 content 传图片在某些模型上报错。
  • 支持模板化 :支持在 content_blocks 结构中挖坑,动态传入图片数据(Base64)和文本提问变量。

(2) 多模态模板最佳实践代码

python 复制代码
import base64
from langchain_core.prompts import ChatPromptTemplate
# 假设 model 已经是支持视觉的多模态大模型

# 1. 定义多模态模板(把问题和图片都做成变量)
multimodal_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个图片分析助手。"),
    ("human", [
        {"type": "text", "text": "请仔细观察图片并回答:{question}"},
        {
            "type": "image",
            "base64": "{base64_image}",
            "mime_type": "image/png"
        }
    ])
])

# 2. 准备图片 base64 数据
def get_image_base64(path):
    with open(path, "rb") as f:
        return base64.b64encode(f.read()).decode("utf-8")

# 3. 填入变量并调用
prompt_value = multimodal_prompt.invoke({
    "question": "图里有什么?瓶盖是什么颜色?",
    "base64_image": get_image_base64("image_test.png")
})
response = model.invoke(prompt_value)
print(response.content)

2. 输出端:提取结构化响应(以 DeepSeek 深度思考为例)

(1) 核心价值

  • 直接读取 response.content 只能拿到最终文本,会丢失模型的思考链(CoT)。
  • 读取 response.content_blocks 可以完整拿到包含 reasoning(思考过程)和 text(最终答案)的结构化列表,常用于前端分离展示(如折叠思考过程)。

(2) 提取深度思考代码示例

python 复制代码
from langchain.chat_models import init_chat_model
# 假设已初始化 model 并启用了思考功能:model = init_chat_model("deepseek...", extra_body={"thinking": {"type": "enabled"}})

# 调用并输出
response = model.invoke("你好,请一句话回答")

# 1. 仅获取最终回答
print(response.content) 

# 2. 结构化获取完整响应(包含思考过程)
print(response.content_blocks)
# 返回格式类似:
# [
#     {'type': 'reasoning', 'reasoning': '用户要求一句话回答...'}, 
#     {'type': 'text', 'text': '你好,有什么我可以为你做的吗?'}
# ]

二、 部分变量预填充 (partial)

1. 核心价值与痛点

  • 类似于 JS 的参数默认值 :如果模板中某些变量(如系统设定的 {role}{audience})在特定场景下是固定的,你可以使用 partial 预先填充并"锁定"它们,避免每次调用 invoke 时都重复传入。
  • 分流派生子模板 :允许从一个通用的"母模板"(比如 你是{department}的{role})派生出多个具体业务场景的"子模板"(如 it_templatesales_template),实现模板的高效复用。这个有点像又搞了一个子类,然后子类可以把父类一些不确定的属性确定下来一样

2. 最佳实践代码

python 复制代码
from langchain_core.prompts import ChatPromptTemplate

# 1. 原始母模板:定义了三个变量
base_template = ChatPromptTemplate.from_messages([
    ("system", "你是{department}的{role}"),
    ("user", "{task}")
])

# 2. 通过 partial() 分别预填充参数(类似于参数柯里化/绑定默认值)
it_template = base_template.partial(department="IT 部门", role="技术支持")
sales_template = base_template.partial(department="销售部门", role="销售顾问")

# 3. 业务调用:此时只需要传入未被填充的 {task} 即可
# 实际执行相当于:sales_template.invoke({"department": "销售部门", "role": "销售顾问", "task": "..."})
result = sales_template.invoke({"task": "为什么年底汽车会促销?"})
print(result)

三、 消息占位符 (MessagesPlaceholder)

1. 核心价值与痛点 (一句话本质区别)

  • 普通变量 {}:解决的是**"消息内部插文字 (String)"**的问题(如给用户提问动态加参数)。
  • 消息占位符:解决的是**"模板内部插消息列表 (ListMessage)"**的问题(如动态插入一整段、甚至几十条多轮对话历史)。

2. 两种定义写法(完全等价)

写法 A:元组占位符 (推荐,最省事)

python 复制代码
template = ChatPromptTemplate.from_messages([
    ("system", "我是一个AI助手"),
    ("placeholder", "{history}")  # 占位符变量名为 history
])

写法 B:MessagesPlaceholder 类 (经典老写法)

python 复制代码
from langchain_core.prompts import MessagesPlaceholder

template = ChatPromptTemplate.from_messages([
    ("system", "我是一个AI助手"),
    MessagesPlaceholder(variable_name="history")  # 效果与上面一致
])

3. 最佳实践代码 (多轮对话历史管理)

python 复制代码
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 假设 model 已经是初始化好的聊天模型

prompt_template = ChatPromptTemplate.from_messages([
    ("system", "你是一个非常友好的AI助手"),
    MessagesPlaceholder(variable_name="history"),  # 给历史记录占座
    ("human", "{question}")                        # 接收用户本次的新提问
])

# 调用时,直接给 history 传入多轮对话 of 列表(可以是元组列表或 Message 对象列表)
prompt_value = prompt_template.invoke({
    "history": [
        ("human", "5 + 2 = ?"),
        ("ai", "5 + 2 = 7")
    ],
    "question": "结果再乘以 4 呢?"
})

# 执行后,LangChain 会自动平铺展开历史记录:
# SystemMessage: 你是一个非常友好的AI助手
# HumanMessage: 5 + 2 = ?
# AIMessage: 5 + 2 = 7
# HumanMessage: 结果再乘以 4 呢?

# response = model.invoke(prompt_value)

四、 可复用提示词模板库 (Prompt Library)

1. 核心价值与痛点 (一句话工程化总结)

  • "提示词大归类" :将项目中散落各处的所有提示词模板(ChatPromptTemplate)统一剪切出来,集中存放于一个独立的文件(如 templates.py)或专门的类中。
  • 解耦降噪:实现了提示词话术与具体业务代码的"高内聚低耦合"。修改提示词文案只需要在此文件/类中修改,业务代码一字不用动,极大方便了非开发人员(PM、Prompt 工程师)的调优与协作。

2. 最佳实践代码

python 复制代码
# 📂 独立文件:templates.py
from langchain_core.prompts import ChatPromptTemplate

class PromptLibrary:
    """可复用的提示词模板库 (集中式管理)"""

    # 1. 翻译模板
    TRANSLATOR = ChatPromptTemplate.from_messages([
        ("system", "你是专业翻译,精通{source_lang}和{target_lang}"),
        ("user", "翻译以下文本:\n{text}")
    ])

    # 2. 摘要模板
    SUMMARIZER = ChatPromptTemplate.from_messages([
        ("system", "你是内容摘要专家"),
        ("user", "将以下内容总结为{num}个要点:\n{content}")
    ])

# ----------------------------------------------------------------

# 📂 具体的业务逻辑代码:main.py
# from templates import PromptLibrary

# 直接点出模板对象并调用,业务代码极度干净
messages = PromptLibrary.TRANSLATOR.invoke({
    "source_lang": "英语",
    "target_lang": "中文",
    "text": "Hello World"
})
相关推荐
木西2 小时前
自动化工程实践:基于 DeepSeek 与 Hardhat 的 Web3 技术长文生成 Skill 实现
openai·agent·deepseek
牧艺2 小时前
从 Chat 到 Agent:Tool Calling 全栈工程化实践
agent·ai编程·全栈
硬核子牙4 小时前
代码展示大模型的智能
linux·chatgpt·agent
smartfish_liu4 小时前
2026-07-17 LLM的自我总结: 今天上午我既不舒服, 又有点喜欢.
agent
老梁agent5 小时前
Agent 记忆的四层存储模型:从 20 条滑窗到长期可演进记忆
agent
jvmind_dev5 小时前
第三章:GC 日志深度分析(上)——多版本、多收集器的统一解析
java·agent
xingxiliang5 小时前
ReliableAgent:类似工程级可用的agent示例
java·开发语言·agent
ArixBit5 小时前
用 Go 手撸 Agent 框架 #9:把最小 Agent 抽成 Runtime
go·agent
Luhui Dev5 小时前
用 AI 生成一道几何题配图:三角形四心作图案例
人工智能·数学·agent·luhuidev