学习大模型RAG和Agent智能体基础知识day4
开头,一些废话
啊哈,又是我!我来更新第四集了!
今天的状态很不错,比平时学的更多,不过令人惊讶的是,没遇到什么麻烦,都是一些比较小的问题,除了数量多一点外并不严重,不过还是和大家分享一下吧,毕竟小问题也要重视,后续再发生就尴尬了!
废话不多说,上源码!
今天主要学习的是简单链的使用以及两种输出处理器。
源码1:langchain中带上历史消息的提示词
# 导入依赖
from langchain_core.prompts import ChatPromptTemplate,MessagesPlaceholder
from langchain_community.chat_models.tongyi import ChatTongyi
# 定义提示词模板,在其中设定一个消息占位
prompt_template = ChatPromptTemplate.from_messages(
[
("system","你是一个有点阴暗,宅宅,但是心地善良的女大学生,带着一副圆框眼镜。住在用户隔壁。那天用户刚刚搬进来,你出门时碰上他了。"),
MessagesPlaceholder("history"),
("human","吃泡面当晚餐不太好吧?晚上要不要一起出去吃个饭?"),
]
)
# 定义历史消息,可以随意添加减少
history = [
("human","你好啊,我刚刚搬来,请多指教!"),
("ai","啊,你你你好(害羞),那个我住在隔壁,请多指教!"),
("human","你在做什么呢?"),
("ai","我,我准备出去买点泡面当晚餐。。。"),
]
# 将历史消息和模板结合
prompt_text = prompt_template.invoke({"history":history}).to_string()
# 定义聊天模型
model = ChatTongyi(model="qwen3-max")
# 将完整的提示词放进模型
response = model.invoke(input=prompt_text)
print(response.content)
# 简单用链进行提示词的注入
# 前面的代码几乎相同
# 定义提示词模板,在其中设定一个消息占位
prompt_template = ChatPromptTemplate.from_messages(
[
("system","你是一个有点阴暗,宅宅,但是心地善良的女大学生,带着一副圆框眼镜。住在用户隔壁。那天用户刚刚搬进来,你出门时碰上他了。"),
MessagesPlaceholder("history"),
("human","吃泡面当晚餐不太好吧?晚上要不要一起出去吃个饭?"),
]
)
# 定义历史消息,可以随意添加减少
history = [
("human","你好啊,我刚刚搬来,请多指教!"),
("ai","啊,你你你好(害羞),那个我住在隔壁,请多指教!"),
("human","你在做什么呢?"),
("ai","我,我准备出去买点泡面当晚餐。。。"),
]
# 这里并没有把历史消息和模板进行结合,而是初始化了一个模型,用链对象把模板和模型连接起来。
model = ChatTongyi(model="qwen3-max",streaming=True)
chain = prompt_template | model
# # 阻塞调用(已注释)
# print(chain.invoke({"history":history}))
# 流式调用
for chunk in chain.stream({"history":history}):
print(chunk.content,end="",flush=True)
这里使用的不再是LLM,而是聊天模型chatmodel,这一点要注意,两者的区别后面会提到。
日志1
简单写一下关于chain链和“|”符号的关系
LangChain 中的 Runnable 基类重写了 or 方法,让两个对象在使用|连接时,返回一个RunnableSequence对象(不论之后链接多少对象,返回的都是这个类),这个对象的父类是Runnable,附上源码:
def __or__(
self,
other: Runnable[Any, Other]
| Callable[[Iterator[Any]], Iterator[Other]]
| Callable[[AsyncIterator[Any]], AsyncIterator[Other]]
| Callable[[Any], Other]
| Mapping[str, Runnable[Any, Other] | Callable[[Any], Other] | Any],
) -> RunnableSerializable[Input, Other]:
"""Runnable "or" operator.
Compose this `Runnable` with another object to create a
`RunnableSequence`.
Args:
other: Another `Runnable` or a `Runnable`-like object.
Returns:
A new `Runnable`.
"""
return RunnableSequence(self, coerce_to_runnable(other))
重点是最后一句:return RunnableSequence(self, coerce_to_runnable(other))
这段return规定将两个输入的对象返回为RunnableSequence对象。
同时,由于父类是Runnable,所以链所属的对象RunnableSequence也是有invoke和stream函数的。
另外,coerce_to_runnable 的作用:
源码中的 coerce_to_runnable(other) 会尝试将非 Runnable 对象(如普通函数、字典)自动转换为 RunnableLambda 或 RunnableParallel,这让 | 非常灵活。
另外,顺便总结一下ChatPromptTemplate,FewShotPromptTemplate和PromptTemplate有什么不同
表格一览:
简单来说,PromptTemplate是有点过时的用法,非常简单直接,将变量填充到字符串中,返回纯文本,平时随便写个测试程序,而且不用提供少量例子时可以用用。服务于LLM。
FewShotPromptTemplate可以提供一些实例让模型照样子回答,一般是实例和前后文拼接而成。一般也用于LLM,有一个适用于chat_model的变体:FewShotChatMessagePromptTemplate
而ChatPromptTemplate则用于现代聊天模型,生成包含 SystemMessage、HumanMessage、AIMessage 等角色的消息列表,支持自动管理对话历史(通过 MessagesPlaceholder)
虽然功能不同,但它们依旧有着同样的最高父类,如图:
源代码2:两种输出解释器
# 导入依赖
from langchain_core.output_parsers import StrOutputParser,JsonOutputParser
from langchain_community.llms.tongyi import Tongyi
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_core.prompts import PromptTemplate
# 定义一个简单模板prompt
prompt = PromptTemplate.from_template("把这些文字翻译成英文:{word}")
# 定义模型
model = Tongyi(model="qwen-max")
# 定义输出解析器
parser = StrOutputParser()
# 定义链
chain = prompt | model | parser | model | parser
print(chain.invoke({"word": "苹果"}))
# 基于两种输出解释器的多模型执行链
# 定义解释器
str_parser = StrOutputParser()
json_parser = JsonOutputParser()
# 定义模型(这里用chat_model)
chat_model = ChatTongyi(model="qwen3-max")
# 定义提示词模板prompt
prompt = PromptTemplate.from_template("请将这些输入文字翻译成英语:{word},并返回JSON格式且只其中包含word这个键。请严格按照要求返回。")
# 定义第二提示词模板prompt_2
prompt_2 = PromptTemplate.from_template("请将这些英文翻译成中文:{word}")
# 定义链
chain = prompt | chat_model | json_parser | prompt_2 | chat_model | str_parser
# 调用链
res = chain.invoke({"word":"服务器费用靠广告维持,还望大家将我们加入AdBlock等广告屏蔽插件白名单!"})
for chunk in res:
print(chunk,end="",flush=True)
chain = prompt | chat_model | json_parser | prompt_2 | chat_model | str_parser
这是一个稍微有点进阶的链,主要在于它把第一次模型调用的结果进行处理后,作为第二次提示词模板的填充物,在模型返回结果的处理上需要记一下方法,这些在下方的日志中有提到。
日志
记录一下几个需要注意的小问题:
- 记得第一次调用模型时返回的结果要先放到JSON输出解释器中,再放到下一个提示词中,不能直接放到模型里。
- 在提示词中下功夫,让模型返回的结果能够被JSON输出解释器识别并处理,特别是要注意规定结果中的键部分要和下一个提示词的填入部分相匹配(如:“请将这些输入文字翻译成英语:{word},并返回JSON格式且只其中包含word这个键。请严格按照要求返回。”)
- LLM和chat_model返回的类型不一样:LLM返回的是纯文本,聊天模型是AI_message。用str输出处理器处理AI_message后得到的就是纯文本str,输出时不能用.content
结尾
好了,就这些,今天确实没什么需要讲的大问题,不过说不定读这篇文章的人刚刚好有一样的疑问,希望可以给予他帮助!晚安!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)