跳至内容

核心抽象层


一、RAG 核心抽象层:Messages、Prompt、Parser


  • 当用户发起提问后,对话生成层按以下顺序工作:
  1. Messages:把用户问题、历史对话、工具返回结果组织成消息序列。
  2. Prompt:把消息、检索到的文档和变量加工成完整提示词。
  3. Parser:把 LLM 返回的文本解析成字符串、JSON 或 Pydantic 对象。
text
用户问题 + 检索文档 + 历史对话
        │ Messages
     消息序列
        │ Prompt
     完整提示词
        │ LLM
     原始输出
        │ Parser
    结构化结果

1. Messages(消息)

1.1 定位

Messages 是与大模型交互的基本数据单元。模型本身只接收消息序列,不直接接收散落的字符串,因此所有对话内容都要先组织成消息。

1.1 核心类型

消息类型 作用
SystemMessage 设定系统角色和回答规则
HumanMessage 表示用户输入
AIMessage 表示模型输出
ToolMessage 表示工具调用后的返回结果

1.2 代码示例

python
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage, ToolMessage

messages = [
    SystemMessage(content="你是一位严谨的金融分析师"),
    HumanMessage(content="请分析这份财报"),
    AIMessage(content="我先查看财报中的关键指标"),
    ToolMessage(content="净利润为 1.2 亿元", tool_call_id="call_001"),
]

1.3 v1.0 新特性:content_blocks

content_blocks 用于统一封装推理、引用和多模态内容。例如同时向模型传入文字和图片:

python
from langchain_core.messages import HumanMessage

message = HumanMessage(
    content_blocks=[
        {"type": "text", "text": "请根据图片判断天气"},
        {
            "type": "image",
            "source": {
                "type": "base64",
                "media_type": "image/jpeg",
                "data": "base64编码的图片数据",
            },
        },
    ]
)

2. Prompt(提示模板)

2.1 定位

Prompt 是动态生成完整提示词的模板引擎。它负责把用户输入、历史对话、检索文档加工成结构化的请求,避免每次手工拼接字符串。

核心类型:

  • PromptTemplate:适合纯文本提示词模板。
  • ChatPromptTemplate:适合 Chat 模型的消息式提示词模板。
  • MessagesPlaceholder:在固定消息之间插入动态消息列表,常用于历史对话。

2.2 PromptTemplate 代码示例

python
from langchain_core.prompts import PromptTemplate

prompt = PromptTemplate.from_template(
    "请用简洁的语言总结以下内容:\n{content}"
)

result = prompt.invoke({"content": "LangChain 是一套用于构建大模型应用的框架。"})
print(result.to_string())

2.3 ChatPromptTemplate + MessagesPlaceholder 代码示例

python
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个{role},请结合检索到的资料回答问题。"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "资料:{context}\n\n问题:{question}"),
])

result = prompt.invoke({
    "role": "智能客服",
    "history": [HumanMessage(content="你好,我想查询余额")],
    "context": "公司产品包含账户查询、转账和理财推荐。",
    "question": "我的余额怎么查询?",
})

print(result.to_messages())

其中 history 也可以传空列表,表示没有历史对话。

3. Parser(输出解析器)

3.1 定位

Parser 负责将 LLM 原始输出解析为结构化数据,让后续代码可以直接使用,而不需要再写复杂的字符串处理逻辑。

3.2 StrOutputParser

StrOutputParser 把输出整理为普通字符串,适合回答类任务。

python
from langchain_core.output_parsers import StrOutputParser

parser = StrOutputParser()
result = parser.invoke("好的,这是最终答案。")

print(result)  # 好的,这是最终答案。

3.3 JsonOutputParser

JsonOutputParser 把 JSON 文本解析为 Python 字典。

python
from langchain_core.output_parsers import JsonOutputParser

parser = JsonOutputParser()
result = parser.invoke('{"name": "张三", "age": 18}')

print(result["name"])  # 张三
print(result["age"])   # 18

3.4 PydanticOutputParser

PydanticOutputParser 根据 Pydantic 模型校验并解析输出,结果字段更稳定。

python
from pydantic import BaseModel, Field
from langchain_core.output_parsers import PydanticOutputParser


class Person(BaseModel):
    name: str = Field(description="人员姓名")
    age: int = Field(description="人员年龄")


parser = PydanticOutputParser(pydantic_object=Person)
person = parser.invoke('{"name": "张三", "age": 18}')

print(person.name)  # 张三
print(person.age)   # 18

二、 完整链路示例

将 Prompt、LLM、Parser 串成一条 LCEL 链,是 RAG 对话生成层最常见的用法:

python
from langchain_core.messages import HumanMessage
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai import ChatOpenAI

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一位严谨的助手,请只根据资料回答。"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "资料:{context}\n\n问题:{question}"),
])

llm = ChatOpenAI(model="gpt-4o-mini")
parser = StrOutputParser()

chain = prompt | llm | parser

answer = chain.invoke({
    "history": [HumanMessage(content="你好")],
    "context": "公司的核心产品是智能客服系统。",
    "question": "公司的核心产品是什么?",
})

print(answer)

如果已经准备好 RAG 检索器,可以把检索结果拼进 context

python
docs = retriever.invoke(question)
context = "\n".join(doc.page_content for doc in docs)

三、 小结

组件 核心任务 核心类型 输出
Messages 组织与大模型交互的基本消息 SystemMessageHumanMessageAIMessageToolMessage 消息序列
Prompt 动态生成完整提示词 ChatPromptTemplatePromptTemplateMessagesPlaceholder 格式化后的提示词
Parser 解析 LLM 原始输出 StrOutputParserPydanticOutputParserJsonOutputParser 字符串、JSON 或 Pydantic 对象

三个组件配合使用,就能把用户问题、历史对话和 RAG 检索文档统一转换成模型可理解的请求,并得到可直接使用的结构化答案。