当前位置: 首页 > news >正文

深入浅出大模型:LangChain详解——打造你的自定义Chain与异步API

分类目录:
《大模型从入门到应用》总目录

LangChain系列文章:

  • 基础知识
  • 快速入门
    • 安装与环境配置
    • 链(Chains)、代理(Agent:)和记忆(Memory)
    • 快速开发聊天模型
  • 模型(Models)
    • 基础知识
    • 大型语言模型(LLMs)
      • 基础知识
      • LLM的异步API、自定义LLM包装器、虚假LLM和人类输入LLM(Human Input LLM)
      • 缓存LLM的调用结果
      • 加载与保存LLM类、流式传输LLM与Chat Model响应和跟踪tokens使用情况
    • 聊天模型(Chat Models)
      • 基础知识
      • 使用少量示例和响应流式传输
    • 文本嵌入模型
      • Aleph Alpha、Amazon Bedrock、Azure OpenAI、Cohere等
      • Embaas、Fake Embeddings、Google Vertex AI PaLM等
  • 提示(Prompts)
    • 基础知识
    • 提示模板
      • 基础知识
      • 连接到特征存储
      • 创建自定义提示模板和含有Few-Shot示例的提示模板
      • 部分填充的提示模板和提示合成
      • 序列化提示信息
    • 示例选择器(Example Selectors)
    • 输出解析器(Output Parsers)
  • 记忆(Memory)
    • 基础知识
    • 记忆的类型
      • 会话缓存记忆、会话缓存窗口记忆和实体记忆
      • 对话知识图谱记忆、对话摘要记忆和会话摘要缓冲记忆
      • 对话令牌缓冲存储器和基于向量存储的记忆
    • 将记忆添加到LangChain组件中
    • 自定义对话记忆与自定义记忆类
    • 聊天消息记录
    • 记忆的存储与应用
  • 索引(Indexes)
    • 基础知识
    • 文档加载器(Document Loaders)
    • 文本分割器(Text Splitters)
    • 向量存储器(Vectorstores)
    • 检索器(Retrievers)
  • 链(Chains)
    • 基础知识
    • 通用功能
      • 自定义Chain和Chain的异步API
      • LLMChain和RouterChain
      • SequentialChain和TransformationChain
      • 链的保存(序列化)与加载(反序列化)
    • 链与索引
      • 文档分析和基于文档的聊天
      • 问答的基础知识
      • 图问答(Graph QA)和带来源的问答(Q&A with Sources)
      • 检索式问答

      • 本摘要(Summarization)、HyDE和向量数据库的文本生成
  • 代理(Agents)
    • 基础知识
    • 代理类型
    • 自定义代理(Custom Agent)
    • 自定义MRKL代理
    • 带有ChatModel的LLM聊天自定义代理和自定义多操作代理(Custom MultiAction Agent)
    • 工具
      • 基础知识
      • 自定义工具(Custom Tools)
      • 多输入工具和工具输入模式
      • 人工确认工具验证和Tools作为OpenAI函数
    • 工具包(Toolkit)
    • 代理执行器(Agent Executor)
      • 结合使用Agent和VectorStore
      • 使用Agents的异步API和创建ChatGPT克隆
      • 处理解析错误、访问中间步骤和限制最大迭代次数
      • 为代理程序设置超时时间和限制最大迭代次数和为代理程序和其工具添加共享内存
    • 计划与执行
  • 回调函数(Callbacks)

创建自定义Chain

要实现自己的自定义链式连接,我们可以子类化
Chain
并实现以下方法:

from __future__ import annotations
from typing import Any, Dict, List, Optional
from pydantic import Extra
from langchain.base_language import BaseLanguageModel
from langchain.callbacks.manager import (AsyncCallbackManagerForChainRun,CallbackManagerForChainRun,
)
from langchain.chains.base import Chain
from langchain.prompts.base import BasePromptTemplateclass MyCustomChain(Chain):"""An example of a custom chain."""prompt: BasePromptTemplate"""Prompt object to use."""llm: BaseLanguageModeloutput_key: str = "text"  #: :meta private:class Config:"""Configuration for this pydantic object."""extra = Extra.forbidarbitrary_types_allowed = True@propertydef input_keys(self) -> List[str]:"""Will be whatever keys the prompt expects.:meta private:"""return self.prompt.input_variables@propertydef output_keys(self) -> List[str]:"""Will always return text key.:meta private:"""return [self.output_key]def _call(self,inputs: Dict[str, Any],run_manager: Optional[CallbackManagerForChainRun] = None,) -> Dict[str, str]:# 在这里编写你的自定义链逻辑# 下面的示例仅模仿了 LLMChainprompt_value = self.prompt.format_prompt(**inputs)# 当调用语言模型或其他链时,应该将回调管理器传递给它。# 这样可以让内部运行受到外部运行注册的任何回调的跟踪。# 你可以通过调用 `run_manager.get_child()` 获取回调管理器,如下所示。response = self.llm.generate_prompt([prompt_value],callbacks=run_manager.get_child() if run_manager else None)# 如果想要记录此次运行的某些信息,可以通过调用 `run_manager` 上的方法来实现。# 这将触发为该事件注册的任何回调。if run_manager:run_manager.on_text("记录此次运行的一些信息")return {self.output_key: response.generations[0][0].text}async def _acall(self,inputs: Dict[str, Any],run_manager: Optional[AsyncCallbackManagerForChainRun] = None,) -> Dict[str, str]:# 在这里编写你的自定义链逻辑# 下面的示例仅模仿了 LLMChainprompt_value = self.prompt.format_prompt(**inputs)# 当调用语言模型或其他链时,应该将回调管理器传递给它。# 这样可以让内部运行受到外部运行注册的任何回调的跟踪。# 你可以通过调用 `run_manager.get_child()` 获取回调管理器,如下所示。response = await self.llm.agenerate_prompt([prompt_value],callbacks=run_manager.get_child() if run_manager else None)# 如果想要记录此次运行的某些信息,可以通过调用 `run_manager` 上的方法来实现。# 这将触发为该事件注册的任何回调。if run_manager:await run_manager.on_text("记录此次运行的一些信息")return {self.output_key: response.generations[0][0].text}@propertydef _chain_type(self) -> str:return "my_custom_chain"from langchain.callbacks.stdout import StdOutCallbackHandler
from langchain.chat_models.openai import ChatOpenAI
from langchain.prompts.prompt import PromptTemplatechain = MyCustomChain(prompt=PromptTemplate.from_template('tell us a joke about {topic}'),llm=ChatOpenAI()
)chain.run({'topic': 'callbacks'}, callbacks=[StdOutCallbackHandler()])

日志输出:

> Entering new MyCustomChain chain...
Log something about this run
> Finished chain.

输出:

Why did the callback function feel lonely? Because it was always waiting for someone to call it back!'
Chain 的异步 API

LangChain通过利用
asyncio
模块提供了对链式连接的异步支持。目前,LLMChain(通过
arun

apredict

acall
方法)、LLMMathChain(通过
arun

acall
方法)、
ChatVectorDBChain
和问答链式连接支持异步方法。其他链式连接的异步支持正在计划中。

import asyncio
import timefrom langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChaindef generate_serially():llm = OpenAI(temperature=0.9)prompt = PromptTemplate(input_variables=["product"],template="What is a good name for a company that makes {product}?",)chain = LLMChain(llm=llm, prompt=prompt)for _ in range(5):resp = chain.run(product="toothpaste")print(resp)async def async_generate(chain):resp = await chain.arun(product="toothpaste")print(resp)async def generate_concurrently():llm = OpenAI(temperature=0.9)prompt = PromptTemplate(input_variables=["product"],template="What is a good name for a company that makes {product}?",)chain = LLMChain(llm=llm, prompt=prompt)tasks = [async_generate(chain) for _ in range(5)]await asyncio.gather(*tasks)s = time.perf_counter()
# If running this outside of Jupyter, use asyncio.run(generate_concurrently())
await generate_concurrently()
elapsed = time.perf_counter() - s
print('\033[1m' + f"Concurrent executed in {elapsed:0.2f} seconds." + '\033[0m')s = time.perf_counter()
generate_serially()
elapsed = time.perf_counter() - s
print('\033[1m' + f"Serial executed in {elapsed:0.2f} seconds." + '\033[0m')

输出:

BrightSmile Toothpaste CompanyBrightSmile Toothpaste Co.BrightSmile ToothpasteGleaming Smile Inc.SparkleSmile Toothpaste
Concurrent executed in 1.54 seconds.BrightSmile Toothpaste Co.MintyFresh Toothpaste Co.SparkleSmile Toothpaste.Pearly Whites Toothpaste Co.BrightSmile Toothpaste.
Serial executed in 6.38 seconds.

参考文献:

[1] LangChain官方网站:https://www.langchain.com/

[2] LangChain 🦜️🔗 中文网,跟着LangChain一起学LLM/GPT开发:https://www.langchain.com.cn/

[3] LangChain中文网 - LangChain 是一个用于开发由语言模型驱动的应用程序的框架:http://www.cnlangchain.com/

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 使用安卓手机安装Kali Linux
  • 基于微信小程序的高校大学生信息服务平台设计与实现
  • 未来不会使用 AI 的人真的会被淘汰吗?
  • iptables和firewalld的区别以及用法
  • 【Golang 面试 - 基础题】每日 5 题(七)
  • Python实战——轻松实现动态网页爬虫(附详细源码)
  • Python 如何创建和操作矩阵?
  • ffmpeg将视频转换成图片
  • 【全面介绍下Gitea,什么是Gitea?】
  • 敏捷产品经理实训:助力产品负责人掌握敏捷方法,提升产品开发效率
  • VB中如何操作数据库(使用ADO.NET连接和查询数据库)
  • 在VMware里面安装Linux安装教程
  • 实时数仓Hologres TPC-H及点查性能开箱测试
  • 电商电子面单API对接方法
  • 【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(十四)-租云服务器及配环境、docker基本命令
  • [case10]使用RSQL实现端到端的动态查询
  • 11111111
  • Android 控件背景颜色处理
  • conda常用的命令
  • JavaScript中的对象个人分享
  • jquery cookie
  • k8s如何管理Pod
  • laravel 用artisan创建自己的模板
  • leetcode讲解--894. All Possible Full Binary Trees
  • MySQL数据库运维之数据恢复
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • underscore源码剖析之整体架构
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 计算机在识别图像时“看到”了什么?
  • 两列自适应布局方案整理
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 一道闭包题引发的思考
  • Nginx实现动静分离
  • ## 1.3.Git命令
  • ###STL(标准模板库)
  • #Datawhale AI夏令营第4期#AIGC方向 文生图 Task2
  • #DBA杂记1
  • #etcd#安装时出错
  • #ifdef 的技巧用法
  • #每日一题合集#牛客JZ23-JZ33
  • (14)Hive调优——合并小文件
  • (175)FPGA门控时钟技术
  • (js)循环条件满足时终止循环
  • (Qt) 默认QtWidget应用包含什么?
  • (备份) esp32 GPIO
  • (二)hibernate配置管理
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (强烈推荐)移动端音视频从零到上手(上)
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (限时免费)震惊!流落人间的haproxy宝典被找到了!一切玄妙尽在此处!
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite