字节跳动青训营 | LangChain实战课学习笔记(15-18)

199 阅读10分钟

一、LangChain中工具及工具箱

1.1LangChain 中工具的概述

1.1.1工具的作用

①工具是代理身上的武器,代理通过工具与世界交互、控制并改造世界。未来的 AI Agent 是以 LLM 为核心控制器的代理系统,工具是代理可以用来与世界交互的功能,如搜索等通用实用程序、其他链或代理。

②LangChain 的强大之处在于大模型的推理能力和工具的执行能力,大模型与工具结合可处理多种类型的任务。

1.1.2工具的定义及工作方式

①在 LangChain 中,工具是通过提供统一框架集成功能的具体实现,每个工具都有输入、输出和处理方法。

②代理接收到任务后,通过大模型推理选择合适工具,LangChain 将任务输入传递给工具,工具处理后生成输出,该输出可作为其他工具输入或最终结果返回给用户。

1.2加载工具的方法

在程序中使用以下代码片段加载工具,某些工具可能需要 LLM 来初始化。

from langchain.agents import load_tools
tool_names = [...]
tools = load_tools(tool_names)# 若某些工具需要 LLM 初始化from langchain.agents import load_tools
tool_names = [...]
llm =...
tools = load_tools(tool_names, llm=llm)

1.3LangChain 支持的工具一览

1.3.1arXiv 工具

①arXiv是一个提供免费访问的预印本库,涵盖多个领域,允许研究者上传未经过同行评议或正式出版的论文,促进学术交流。

②使用方法:

1. 设置 OpenAI API 的密钥。

2. 导入库。

3. 初始化模型和工具,可通过load_tools加载arxiv工具,并传入ChatOpenAI实例。

4. 初始化链,指定代理类型为AgentType.ZERO_SHOT_REACT_DESCRIPTION。

5. 运行链,传入问题让代理回答。

1.3.2LangChain 中的工具箱一览:

Gmail 工具箱:可通过 LangChain 应用检查邮件、删除垃圾邮件、撰写邮件草稿。

Office365 工具箱:可让 LangChain 应用读写文档、总结文档、做 PPT。

GitHub 工具箱:可指示 LangChain 应用检查最新代码、Commit Changes、Merge Branches,甚至让大模型自动回答 Issues 中的问题。

1.4使用 Gmail 工具箱开发个人助理

在 Google Cloud 中设置应用程序接口:跟随 Gmail API 的官方配置链接完成,配置过程较复杂,需耐心按照流程进行。

根据密钥生成开发 Token

①安装相关包,如google-api-python-client、google-auth-oauthlib、google-auth-httplib2。

②下载密钥保存为credentials.json,运行代码生成token.json。

用 LangChain 框架开发 Gmail App

①连接到 Gmail API,查询用户邮件,通过 LangChain 的 Agent 框架智能化调用 API,与邮件进行互动。

②核心代码包括设置 API 密钥、导入与 Gmail 交互的工具包、初始化 Gmail 工具包、获取工具、初始化聊天模型、通过指定工具和聊天模型初始化 agent 并运行查询指令。

二、通过RAG助力鲜花运营

2.1RAG(检索增强生成)概述

定义:Retrieval-Augmented Generation,结合检索和生成能力,为文本序列生成任务引入外部知识,将传统语言生成模型与大规模外部知识库结合,使模型在生成响应时可从知识库检索相关信息。

工作原理

①检索:对于给定输入,使用检索系统从大型文档集合中查找相关文档或段落,通常基于密集向量搜索。

②上下文编码:将找到的相关文档或段落与原始输入一起编码。

③生成:使用编码的上下文信息,通过大模型生成输出。

2.2RAG 在 LangChain 中的应用

(1) 文档加载

LangChain 提供多种文档加载器,可加载各种类型文档,并与 Airbyte、Unstructured.IO 等集成。

(2) 文本转换

文本分割

原理: 将文本分成小的、具有语义意义的块,组合成更大的块,达到一定大小后形成新块并与上一块有重叠以保持上下文。

考量因素:

LLM 限制:根据模型上下文窗口大小确定文本块大小。

任务类型:细致任务用较小分块,全面了解文本的任务用较大分块。

文本性质:结构强的文本用较大块,结构弱的文本用较小块。

其他形式的文本转换

过滤冗余文档: 使用 EmbeddingsRedundantFilter 工具识别相似文档并过滤冗余信息。

翻译文档: 通过与 doctran 集成进行文档翻译。

提取元数据: 从文档内容中提取关键信息存储为元数据。

转换对话格式: 将对话式文档内容转化为问答格式。

(3) 文本嵌入

①通过 LLM 将文本转换为数值表示,便于计算机处理和比较。OpenAI、Cohere、Hugging Face 中有能做文本嵌入的模型。

②LangChain 中的 Embeddings 类为所有文本嵌入模型提供标准接口,有 embed_documents 和 embed_query 两种方法,分别为文档和查询创建嵌入。

(4) 存储嵌入

缓存存储

CacheBackedEmbeddings 是支持缓存的嵌入式包装器,可将嵌入缓存在键值存储中,对文本哈希处理后用作缓存键。

不同缓存策略:InMemoryStore 用于内存中缓存,适用于单元测试或原型设计;LocalFileStore 在本地文件系统中存储嵌入;RedisStore 在 Redis 数据库中缓存嵌入。

向量数据库(向量存储)

LangChain 支持多种向量数据库,如 Elasticsearch、Faiss、Chroma 和 Qdrant 等。选择时需考虑数据规模和速度需求、持久性和可靠性、易用性和社区支持、成本、特性、安全性等因素,并进行性能基准测试。

(5) 数据检索

向量存储检索器:通过 VectorstoreIndexCreator 创建索引,可在索引的 query 方法中,将向量数据库作为检索器完成检索任务。VectorstoreIndexCreator 封装了 vectorstore、embedding 以及 text_splitter 等工具。

各种类型的检索器:LangChain 提供多种其他检索工具。

(6) 索引

索引是高效管理和定位文档信息的方法,LangChain 利用记录管理器跟踪文档状态和来源,确保文档数据被正确管理和索引。对每个文档哈希处理,确保唯一标识,并保存文档哈希、写入时间和源 ID 等信息。

三、通过链和代理查询鲜花信息

3.1传统数据库查询与新范式对比

传统数据库查询:使用结构化查询语言(SQL)从数据库提取信息或进行操作,需要深入了解技术和所操作数据,具备程序员基本技能和知识。

新数据库查询范式

①随着人工智能和大语言模型发展,可使用自然语言与计算机交互,从 “告诉计算机每一步怎么做” 转变为 “告诉计算机我们想要什么”,更加人性化和高效。

②流程包括用户用自然语言提出问题,LLM 理解并转译问题为 SQL 查询语句,执行 SQL 查询后数据库返回结果,LLM 接收并解释结果,最后将结果转化为自然语言答案返回给用户。

3.2实战案例

背景信息:业务数据存储在数据库中,目标是通过自然语言为销售的鲜花数据创建查询,可作为查询工具供员工使用,也可整合到聊天机器人为顾客服务。

创建数据库表

①使用 SQLite 作为示例数据库,它是轻量级磁盘文件数据库,支持 ACID,适合桌面、嵌入式或初创企业应用,Python 内置的 sqlite3 库可方便创建、查询和管理 SQLite 数据库。

②代码中连接到数据库FlowerShop.db,创建Flowers表存储鲜花相关数据,包括 ID、名称、类型、来源、采购价、售价、库存数量、销售数量、过期日期、描述和录入日期等字段,插入 5 种鲜花数据后提交更改并关闭连接。

用 Chain 查询数据库

①由于 LangChain 的数据库查询功能较新处于实验阶段,需安装langchain-experimental包。

②导入必要模块后连接到FlowerShop.db数据库,初始化 OpenAI 的 LLM 实例,用SQLDatabaseChain创建从 LLM 到数据库的链接,通过db_chain.run()方法查询多个与鲜花运营相关的问题,内部将自然语言转换为 SQL 语句查询数据库表,再把结果转换为自然语言。

用 Agent 查询数据库

①LangChain 可通过 SQL Agent 完成查询任务,相比SQLDatabaseChain,使用 SQL 代理可根据数据库架构和内容回答问题,具有纠错能力。

②使用create_sql_agent函数创建 SQL 代理,包含SQLDatabaseToolkit,其中有创建并执行查询、检查查询语法、检索数据表描述等工具,辅助代理驱动 LLM 完成 SQL 查询任务。

四、回调函数

4.1回调函数和异步编程

回调函数概念:函数 A 作为参数传给另一个函数 B,在函数 B 内部执行函数 A,常见于处理异步操作如事件监听、定时任务或网络请求。

异步编程

①异步是指代码不必等待某个操作完成(如 I/O 操作、网络请求、数据库查询等)就可以继续执行的能力,与同步编程形成对比。

②示例中展示了在异步操作时使用回调函数,如模拟异步操作并在不同任务间切换执行,体现异步编程可同时执行多个操作,无需等待一个完成后再开始另一个。

4.2LangChain 中的 Callback 处理器

机制介绍:LangChain 的 Callback 机制通过 CallbackHandler(回调处理器)实现,为每类可监控的事件提供方法,BaseCallbackHandler 是最基本的回调处理器,可继承创建自定义处理器,LangChain 也提供内置处理器如 StdOutCallbackHandler 和 FileCallbackHandler。

在组件中使用:LangChain 各个组件如 Chains、Models、Tools、Agents 等提供构造函数回调和请求回调两种设置方法,可在初始化或单独请求中传入回调处理器,如结合使用 LangChain 的回调机制与 loguru 日志库可同时输出到标准输出和文件。

4.3自定义回调函数

示例:通过 BaseCallbackHandler 和 AsyncCallbackHandler 自定义回调函数,如在鲜花店客服程序中使用同步和异步回调,同步回调在新 Token 生成时打印信息,异步回调模拟异步获取花卉信息及结束操作,体现异步操作在程序中的优势,包括模拟延时操作、回调机制和事件循环。

import asyncio
from typing import Any, Dict, List

from langchain.chat_models import ChatOpenAI
from langchain.schema import LLMResult, HumanMessage
from langchain.callbacks.base import AsyncCallbackHandler, BaseCallbackHandler

# 创建同步回调处理器
class MyFlowerShopSyncHandler(BaseCallbackHandler):
    def on_llm_new_token(self, token: str, **kwargs) -> None:
        print(f"获取花卉数据: token: {token}")

# 创建异步回调处理器
class MyFlowerShopAsyncHandler(AsyncCallbackHandler):

    async def on_llm_start(
        self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
    ) -> None:
        print("正在获取花卉数据...")
        await asyncio.sleep(0.5)  # 模拟异步操作
        print("花卉数据获取完毕。提供建议...")

    async def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None:
        print("整理花卉建议...")
        await asyncio.sleep(0.5)  # 模拟异步操作
        print("祝你今天愉快!")

# 主要的异步函数
async def main():
    flower_shop_chat = ChatOpenAI(
        max_tokens=100,
        streaming=True,
        callbacks=[MyFlowerShopSyncHandler(), MyFlowerShopAsyncHandler()],
    )

    # 异步生成聊天回复
    await flower_shop_chat.agenerate([[HumanMessage(content="哪种花卉最适合生日?只简单说3种,不超过50字")]])

# 运行主异步函数
asyncio.run(main())

异步体现

①模拟延时操作:通过 await asyncio.sleep (0.5) 模拟异步操作,释放控制权回到事件循环,允许其他异步任务处理。

②回调机制:ChatOpenAI 在处理新 Token 时调用同步回调,异步回调在开始和结束时有延时操作模拟异步获取信息。

③事件循环:Python 的 asyncio 库提供事件循环,允许多个异步任务并发运行。

4.4用 get_openai_callback 构造令牌计数器

回忆记忆机制与 Token 消耗:回忆第 11 课中的记忆机制及各种记忆机制对 Token 的消耗数量估算。

通过回调函数重构程序:使用 get_openai_callback 上下文管理器监控与 OpenAI 交互的 Token 数量,在特定事件发生时执行操作或收集信息,如计算与 ConversationChain 交互中使用的总 Tokens 数,还可添加异步函数演示在多个并发交互中计算 Tokens。