如何使用LangChain、RStudio和足够的Python生成人工智能( 二 )


Python新手的关键点:不要将脚本文件的名称与将要加载的Python模块的名称相同!换句话说,虽然该文件不必命名为prep_docs.py,但如果要导入langchain包,就不要将其命名为langchain.py !它们会发生冲突 。这在R中并不是问题 。
以下是新的prep_docs.py文件的第一部分:
If running from RStudio, remember to first run in R:# library(reticulate)# use_virtualenv("the_virtual_environment_you_set_up")# api_key_py <- r_to_py(Sys.getenv("OPENAI_API_KEY"))from langchain.document_loaders import PyPDFLoadermy_loader = PyPDFLoader('docs/ggplot2.pdf')# print(type (my_loader))all_pages = my_loader.load()# print(type(all_pages)) print( len(all_pages) )这段代码首先导入PDF文档加载器PyPDFLoader 。接下来,它创建PDF加载器类的一个实例 。然后,它运行加载器及其load方法 , 将结果存储在一个名为all_pages的变量中 。该对象是一个Python列表 。
在这里包含了一些注释行,如果想看到它们,它们将打印对象类型 。最后一行打印列表的长度,在本例中是304 。
可以点击RStudio中的source按钮来运行一个完整的Python脚本 。或者,突出显示一些代码行并只运行它们,就像使用R脚本一样 。Python代码在运行时看起来与R代码略有不同,因为它在R控制台中打开一个Python交互式REPL会话 。用户将被指示输入exit或quit(没有括号)以退出并在完成后返回常规R控制台 。

如何使用LangChain、RStudio和足够的Python生成人工智能

文章插图
用户可以使用reticulate的py对象在R中检查all_pages Python对象 。下面的R代码将Python all_pages对象存储到一个名为all_pages_in_r的R变量中(用户可以随意调用它) 。然后,可以像处理任何其他R对象一样处理该对象 。在本例中,它是一个列表 。
all_pages_in_r <- py$all_pages# Examples:all_pages_in_r[[1]]$metadata # See metadata in the first itemnchar(all_pages_in_r[[100]]$page_content) # Count number of characters in the 100th itemLangChain集成
如果用户还没有最喜欢的将PDF转换为可读文本的方法,那么LangChain的PyPDFLoader可以方便地用于其他非人工智能项目 。而且,LangChain还有100多种其他文件加载器,包括PowerPoint、word、网页、YouTube、epub、Evernote和Notion等格式 。可以在LangChain集成中心中看到一些文件格式和集成文档加载器 。
步骤3:将文档拆分为多个部分LangChain有几个转换器可以将文档分解成块,包括按字符、标记和标记头进行拆分 。一个推荐的默认值是RecursiveCharacterTextSplitter,它将“递归地尝试按不同的字符进行拆分,以找到一个有效的字符” 。另一个流行的选项是CharacterTextSplitter,它的设计目的是让用户设置其参数 。
用户可以设置该拆分器的最大文本块大小,是按字符计数还是按LLM令牌计数(令牌通常是1到4个字符),以及文本块应该重叠多少 。在开始使用LangChain之前,从未考虑过文本块重叠的必要性,但它是有意义的,除非用户可以通过逻辑块(如用标题分隔的章节或节)来分隔 。否则 , 文本可能会在句子中间被拆分 , 一个重要的信息可能会被分成两个部分 , 其中任何一个都没有明确的完整含义 。
用户还可以选择希望拆分器在分割文本时优先考虑哪些分隔符 。CharacterTextSplitter的默认值是首先拆分为两个新行(nn),然后再拆分一个新行、一个空格,最后完全不使用分隔符 。
下面的代码通过使用Python内部的reticulate的R对象,从R api_key_for_py变量导入OpenAI API密钥 。它还加载openai Python包和LangChain的递归字符分割器,创建一个RecursiveCharacterTextSplitter类的实例,并在all_pages块上运行该实例的split_documents()方法 。
import openaiopenai.api_key = r.api_key_for_py from langchain.text_splitter import RecursiveCharacterTextSplittermy_doc_splitter_recursive = RecursiveCharacterTextSplitter()my_split_docs = my_doc_splitter_recursive.split_documents(all_pages)同样,用户可以用R代码将这些结果发送给R,例如:
My_split_docs <- py$ My_split_docs是否想知道块中的最大字符数是多少?可以用R中的一个自定义函数来检查这个列表:
get_characters <- function(the_chunk) {x <- nchar(the_chunk$page_content)return(x)}purrr::map_int(my_split_docs, get_characters) |>max()这将生成3,985个字符,因此看起来默认的块最大值是4,000个字符 。
如果想要更小的文本块,首先尝试CharacterTextSplitter并人工地将chunk_size设置为小于4,000,例如
chunk_size = 1000chunk_overlap = 150from langchain.text_splitter import CharacterTextSplitterc_splitter = CharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap, separator=" ")c_split_docs = c_splitter.split_documents(all_pages)print(len(c_split_docs)) # To see in Python how many chunks there are now


推荐阅读