关于我 壹文 项目 三五好友
🚀 LangChain 探险手册 🌟 2024-07-07

一、🎓 初识LangChain

LangChain是一个强大的工具,它可以让你和AI模型进行深入的交流。就像学会了咒语一样,你可以指挥AI去完成各种任务。

🛠️ 环境搭建

  • 武器库: Python + Jupyter notebook
  • 秘籍: 交互式学习,让你在探索中获得即时的魔法反馈。

📦 安装LangChain

pip install langchain

🔧 小提示: 如果你使用的是Python3.x,可能需要用 pip3 来安装哦!

🔧 快速开始

  • 魔法组件: HumanMessage, SystemMessage
  • 施展魔法: 将英文翻译成意大利语

3、直接使用模型做一个小例子

# 导入了 LangChain 库中的 HumanMessage 和 SystemMessage 类。
# 这些类用于表示人类消息和系统消息
from langchain_core.messages import HumanMessage, SystemMessage

messages = [
    SystemMessage(content="将以下内容从英文翻译成意大利语"),
    HumanMessage(content="hi!"),
]
# invoke() 方法是 LangChain 库中用于执行语言模型的推理任务的方法
# 施展翻译魔法
model.invoke(messages)

📐 输出解析器 OutputParsers

  • AI的回应 通常包含一个字符串响应以及有关响应的其他元数据
  • 通常我们可能只想处理字符串响应,使用 StrOutputParser 让回应变得清晰易懂
from langchain_core.output_parsers import StrOutputParser

parser = StrOutputParser()

# 可以单独使用它
result = model.invoke(messages)

parser.invoke(result)
# 'Ciao!'

///
# 我们也可以使用`链 |`将模型与输出解析器连在一起,完成自动的链式执行
chain = model | parser

chain.invoke(messages)  # 输出: Ciao!

📝 提示词模板 Prompt Templates

目前我们直接将消息列表传递给语言模型。这个消息列表从何而来?通常,它是从用户输入和应用程序逻辑的组合中构建的。

  • 动态填充你的魔法咒语模板
  • 结合用户输入和应用逻辑,施展个性化魔法
from langchain.prompts import PromptTemplate

# 定义一个模板,其中包含两个占位符
template = "你好,我是 {name}。我 {age} 岁。"
prompt = PromptTemplate(
    input_variables=["name", "age"],
    template=template
)

# 在运行时填充占位符
print(prompt.format(name="Alice", age=25))  # 输出: 你好,我是 Alice。我 25 岁。

🌐 部署服务 Serving with LangServe

  • 将你的LangChain魔法链变成所有人都能访问的REST API
  • 使用 FastAPI 构建你的魔法服务器

📦 安装LangServe

首先,我们需要安装LangServe

pip install "langserve[all]"

🔨 构建魔法服务器

接下来,我们将创建一个 serve.py 文件。它包含三个部分:

  1. 我们刚刚构建的链
  2. 我们的 FastAPI 应用程序
  3. 使用 langserve.add_routes 定义的服务链的路由
#!/usr/bin/env python
# 导入 Python 的 typing 模块,用于类型注释
from typing import List
# 导入 FastAPI 框架,用于创建 API 服务器
from fastapi import FastAPI
# 导入 LangChain 库中的 ChatPromptTemplate 类,用于创建聊天提示模板
from langchain_core.prompts import ChatPromptTemplate
# 导入 LangChain 库中的 StrOutputParser 类,用于解析模型的输出
from langchain_core.output_parsers import StrOutputParser
# 导入 LangChain 库中的 ChatOpenAI 类,用于创建 OpenAI 聊天模型
from langchain_openai import ChatOpenAI

from langserve import add_routes

# 1. 创建魔法模板,指定翻译的语言
# 定义一个系统消息模板,用于指定要将内容翻译成哪种语言
system_template = "将以下内容翻译成{language}:"
prompt_template = ChatPromptTemplate.from_messages([
    ('system', system_template),
    ('user', '{text}')
])

# 2. 召唤OpenAI模型,准备施展翻译魔法
model = ChatOpenAI()

# 3. 创建解析器
parser = StrOutputParser()

# 4. 创建链
chain = prompt_template | model | parser

# 4. 创建FastAPI应用,作为魔法秀场的舞台
app = FastAPI(
  title="LangChain Server",
  version="1.0",
  description="使用 LangChain Runnable 接口的简单 API 服务器",
)

# 5. 添加链路由,我们将魔法链添加到我们的秀场中,让所有人都能通过特定的路径来观看魔法表演。
add_routes(
    app,
    chain,
    path="/chain",
)

if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="localhost", port=8000)

🎬 启动魔法秀场

现在,一切都已准备就绪,只需运行以下命令,我们的魔法秀场就会开启。

python serve.py

访问 http://localhost:8000 ,你将看到LangChain的魔法在闪耀。

🎪 魔法秀场的内置UI

每个LangServe服务都有一个简单的内置UI,你可以在这里配置和调用魔法,甚至可以看到魔法施展的中间步骤。

🤖 远程施展魔法

如果你想远程施展魔法,可以使用客户端的形式进行交互测试。

from langserve import RemoteRunnable

# 创建一个远程魔法链
remote_chain = RemoteRunnable("http://localhost:8000/chain/")
# 施展魔法:将"hi"翻译成意大利语
remote_chain.invoke({"language": "italian", "text": "hi"})
# 'Ciao'

🤖 构建你的聊天机器人

🌟 介绍

欢迎来到LangChain的魔法世界,在这里我们将一起探索如何构建一个能够进行对话并记住先前交互的聊天机器人。🧙‍♂️🤖

🧰 高级组件一览

  • 聊天模型:不同于普通的文本大语言模型,聊天模型围绕消息构建,更适合对话场景。
  • 提示模板:简化了消息、用户输入和聊天历史的组合过程。
  • 聊天历史:让机器人能够“记住”过去的对话,为后续交互提供上下文。

🗂️ 为什么我们需要聊天历史?

想象一下,如果你的机器人每次对话都像失忆一样,那该多尴尬啊!😅 所以,我们需要聊天历史来让机器人记住用户的信息。

📚 示例:没有聊天历史的情况

from langchain_core.messages import HumanMessage

model.invoke([HumanMessage(content="Hi! I'm Bob")])
# 当Bob问起他的名字时...
model.invoke([HumanMessage(content="What's my name?")])
# 机器人尴尬地回答不知道... 😬

🔄 改进:使用聊天历史

通过将对话历史传递给模型,Bob再次询问他的名字时,机器人就能回答上来了!👍

# 机器人现在能够记住Bob的名字了!
model.invoke([
    HumanMessage(content="Hi! I'm Bob"),
    # ...其他对话...
    HumanMessage(content="What's my name?")
])
# 机器人回答:'Your name is Bob.'

🏗️ 使用Message History

我们将使用消息历史类来包装我们的模型,让它具有记忆能力,就像给机器人装上了一个记忆芯片!🧠

🛠️ 安装必要的库

首先,我们需要安装 langchain-community 来帮助我们存储和管理聊天历史。

pip install langchain_community

📝 设置消息历史

接下来,我们将设置一个函数来获取会话历史,这样我们的机器人就可以根据不同的 session_id 来区分不同的对话。

from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory
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] = ChatMessageHistory()
    return store[session_id]

🔗 将模型与消息历史结合

现在,我们将模型与消息历史结合起来,创建一个具有记忆功能的聊天机器人。

with_message_history = RunnableWithMessageHistory(model, get_session_history)

🔧 配置会话

每次调用机器人时,我们需要提供一个配置,包含 session_id,这样机器人就知道是在和谁对话了。

config = {"configurable": {"session_id": "abc123"}}

# 现在Bob可以愉快地和机器人聊天了!
response = with_message_history.invoke(
    [HumanMessage(content="Hi! I'm Bob")],
    config=config,
)
print(response.content)  # 'Hello Bob! How can I assist you today?'

📑 管理对话历史

随着对话的进行,如果不加管理,消息列表会越来越长,可能会超出机器人的记忆范围。🚫

🔐 限制消息大小

我们可以通过添加一个步骤来限制消息的数量,只保留最近的几条消息。

from langchain_core.runnables import RunnablePassthrough

def filter_messages(messages, k=10):
    return messages[-k:]

# 创建一个新的链,包括消息过滤、提示模板、模型
chain = (
    RunnablePassthrough.assign(messages=lambda x: filter_messages(x["messages"]))
    | prompt
    | model
)

💬 流式传输

最后,为了让用户能够实时看到机器人的思考过程,我们可以利用流式传输功能。

🚀 实现流式传输

所有链都提供了 .stream() 方法,我们可以利用这个方法来实现流式输出。

# 假设我们已经有一个配置好的chain
for token in chain.stream(...):
    print(token, end='', flush=True)

这样,用户就可以看到每个单词或句子是如何逐个生成的,提升了交互体验。🎉

🎈恭喜你,现在你已经掌握了构建一个具有记忆功能的聊天机器人的魔法!🎉

Not-By-AI