作者:CSDN博客
什么是LangChain?
LangChain本质上是一个开源的框架,提供一些工具、接口帮你快速创建由LLM和聊天模型支持的应用程序。所以说它本身只是帮你调整大模型构建特定功能的应用,所以你还需要有大模型,一般我们都使用其他公司的大模型api,如OpenAI,Gemini等。
LangChain简化了LLM应用程序生命周期的每个阶段:
开发:使用LangChain的开源组件和第三方集成构建您的应用程序。使用LangGraph构建具有一流流式传输和人工参与支持的状态代理
生产化:使用LangSmith来检查、监控和评估应用程序,以便可以持续优化并充满信心的部署
部署:使用LangGraph Platform将LangGraph应用程序转变为生产就绪的API和助手。
基础使用教程
一、拉取langchain
二、langchain简单使用
1、引入大模型
- import os
- from langchain_openai import ChatOpenAI
- os.environ["OPENAI_API_KEY"] = "API-key"
- llm = ChatOpenAI(
- base_url="https://api.hunyuan.cloud.tencent.com/v1",
- model="hunyuan-turbos-latest",
- temperature=0.5
- )
复制代码参数解析:
os.environ["OPENAI_API_KEY"] = "API密钥",申请的模型apikey
base_url:大模型的部署调用地址
model:调用的模型名称(官方发布的模型名称)
temperature:模型温度,温度越高越具有创造力
引申:
openAI国内用不了,使用腾讯混元大模型代替(免费):console.cloud.tencent.com
2、简单调用大模型
- from langchain_core.messages import HumanMessage, SystemMessage
- messages = [
- SystemMessage(content="Translate the following from English into China"),
- HumanMessage(content="What is the capital of France?")
- ]
- result = llm.invoke(messages)
- print(result.content)
复制代码解析:
SystemMessage:系统消息,告诉系统他的作用,或者他扮演的角色
HumanMessage:用户消息,该方法存放用户与大模型交互的信息
llm.invoke(messages):将消息传送给大模型,并激活大模型进行处理消息
result.content:拿到大模型返回的结果内容
引申:
输出解析器
文本效果等同于result.content- from langchain_core.output_parsers import StrOutputParser
- parser = StrOutputParser()
- result = llm.invoke(messages)
- response = parser.invoke(result)
- print(response)
复制代码 3、模板处理
- from langchain_core.messages import HumanMessage
- from langchain_core.prompts import ChatPromptTemplate,MessagesPlaceholder
- prompt = ChatPromptTemplate.from_messages(
- [
- (
- "system",
- "你是一个翻译机器人,你需要识别语言,并且将其翻译为{language}。"
- ),
- MessagesPlaceholder(variable_name="messages")
- ]
- )
- resul = prompt.invoke(
- {
- "messages": [HumanMessage(content="你好!我是鲍勃")],
- "language": "English"
- }
- )
- response = llm.invoke(resul.to_messages())
- print(response.content)
复制代码解析:
ChatPromptTemplate:定义一个模板prompt,其中占位符用{}
MessagesPlaceholder(variable_name="messages"):定义一个未知消息类型占位符,名称为messages。消息类型有SystemMessage、HumanMessage、AIMessage
prompt.invoke:激活并使用模板,将占位符填充内容
resul.to_messages():将填充后的模板转换为messages,后续提供给大模型使用
4、LCEL(组件连接)
- chain = prompt_template | llm | parser
- chain.invoke({"language": "italian", "text": "hi"})
复制代码解析:
chain:定义一个LCEL链式处理串
chain.invoke:激活chain处理传入内容
执行顺序:激活穿入的内容传递到LCEL处理。先进行模板处理,然后在将处理后的模板传递给llm,最后在将llm处理的内容交给parser进行输出解析
三、langchain基础使用
1、会话记忆(历史消息)
让我们确保安装 langchain-community,因为我们将使用其中的集成来存储消息历史记录。
定义历史消息存储
- from langchain_core.chat_history import (
- BaseChatMessageHistory,
- InMemoryChatMessageHistory,
- )
- from langchain_core.runnables.history import RunnableWithMessageHistory
- store = {}
- def get_session_history(session_id: str) -> BaseChatMessageHistory:
- if session_id not in store:
- store[session_id] = InMemoryChatMessageHistory()
- return store[session_id]
- with_message_history = RunnableWithMessageHistory(llm, get_session_history)
复制代码解析:
get_session_history:定义获取历史信息方法
RunnableWithMessageHistory(llm, get_session_history):为模型添加历史信息
调用大模型
- config = {"configurable": {"session_id": "abc2"}}
- response = with_message_history.invoke(
- [HumanMessage(content="Hi! I'm Bob")],
- config=config,
- )
- response.content
复制代码解析:
config:定义当前会话的session_id
with_message_history.invoke:激活历史信息模型,并且将config应用
设置历史消息上下文长度
- from langchain_core.messages import SystemMessage,HumanMessage,AIMessage, trim_messages
- # 模拟token计算方法
- def simple_token_counter(messages):
- # 假设每个空格分隔的词算一个 token
- return sum(len(msg.content.split()) for msg in messages)
- # 2、设置上下文截取token的大小
- trimmer = trim_messages(
- max_tokens=20,
- # 已修剪消息的最大令牌计数
- strategy="last",
- # 修剪策略。
- # - “first”:保留消息的前 <= n_count 个令牌。
- # - “last”:保留消息的最后 <= n_count 个令牌。
- # 默认值为 “last”。
- token_counter=simple_token_counter,
- # 用于对 BaseMessage 或 BaseMessage 列表中的令牌进行计数的函数或 llm
- include_system=True,
- # 如果索引 0 处有 SystemMessage,是否保留 SystemMessage。
- # 仅当 strategy=“last” 时才应指定。默认值为 False。
- allow_partial=False,
- #如果只能包含消息的一部分,是否拆分消息。如果 strategy=“last” 则包含消息的最后部分内容。
- # 如果 strategy=“first” 则包含消息的第一个部分内容。默认值为 False。
- start_on="human",
- # 要开始的消息类型。仅当 strategy=“last” 的 intent 函数。
- # 如果指定,则忽略此类型首次出现之前的每条消息。这是在我们将初始消息修剪到最后一个 max_tokens 后完成的。
- # 如果 include_system=True,则不适用于索引 0 处的 SystemMessage。
- # 可以指定为字符串名称(例如 “system”、“human”、“ai” 等)或 BaseMessage 类(例如 SystemMessage、HumanMessage、AIMessage 等)。
- # 可以是单个类型或类型列表。默认值为 None。
- )
- ...
- from langchain_core.runnables import RunnablePassthrough
- chain = (
- RunnablePassthrough.assign(messages=itemgetter("messages") | trimmer)
- # itemgetter 用于获取对象的哪些位置的数据,参数即为代表位置的序号值。
- | prompt
- | llm
- )
复制代码解析:
itemgetter("messages") | trimmer :拿到messages的值,并进行trimmer切割
RunnablePassthrough.assign:创建一个新的可运行对象,它会保留原始输入的所有字段,同时添加或替换指定的字段。此处指定为messages
2、模型流式返回
- prmopt = ChatPromptTemplate.from_messages(
- [
- (
- "system",
- "你是一个聊天助手,你的输出语言是{language}"
- ),
- MessagesPlaceholder(variable_name="messages")
- ]
-
- )
- chain = prmopt | llm
- with_message_history = RunnableWithMessageHistory(
- chain,
- get_session_history,
- input_messages_key="messages", # 由于输入中有多个 key,我们需要指定正确的 key 来保存聊天记录
- )
- for r in with_message_history.stream(
- {
- "messages": [HumanMessage(content="hi! I'm todd. tell me a joke")],
- "language": "China",
- },
- config=config
- ):
- print(r.content, end="|")
复制代码 原文地址:https://blog.csdn.net/qq_56796761/article/details/149279789 |