paper-qa

paper-qa

基于文档的智能问答系统 实现精准信息检索和回答生成

paper-qa是一款轻量级文档问答工具包,专门从PDF和文本文件中提取信息并生成回答。通过文档嵌入、向量搜索和摘要生成等技术,结合大型语言模型,paper-qa能够提供高质量且有据可依的回答。支持OpenAI、Anthropic等多种嵌入和语言模型,并可集成本地托管模型。工具提供异步API,支持自定义文档添加和引用格式推断,还可整合外部向量存储。这些特性使paper-qa成为科研和信息检索领域的实用解决方案。

PaperQA文献问答嵌入式向量LLM异步处理Github开源项目

PaperQA

GitHub tests PyPI version

这是一个用于对PDF或文本文件(可以是原始HTML)进行问答的简洁软件包。它致力于通过在文本中引用来源,提供非常优质的答案,避免产生幻觉。

默认情况下,它使用OpenAI Embeddings和一个简单的numpy向量数据库来嵌入和搜索文档。然而,通过langchain,你也可以使用开源模型或嵌入(详情见下文)。

paper-qa使用以下流程:

  1. 将文档嵌入为向量
  2. 将查询嵌入为向量
  3. 在文档中搜索前k个相关段落
  4. 为每个与查询相关的段落创建摘要
  5. 使用LLM重新评分并仅选择相关摘要
  6. 将摘要放入提示中
  7. 用提示生成答案

更多详情请参阅我们的论文:

@article{lala2023paperqa, title={PaperQA: Retrieval-Augmented Generative Agent for Scientific Research}, author={L{\'a}la, Jakub and O'Donoghue, Odhran and Shtedritski, Aleksandar and Cox, Sam and Rodriques, Samuel G and White, Andrew D}, journal={arXiv preprint arXiv:2312.07559}, year={2023} }

输出示例

问题:如何大规模制造碳纳米管?

碳纳米管可以使用电弧技术进行大规模制造(Journet6644)。这种技术涉及在氦气氛围的反应器中,在两个电极之间产生电弧,并在阳极中使用金属催化剂和石墨粉的混合物。这种方法可以获得80%的缠绕碳纤维产率,这些纤维由较小的对齐单壁碳纳米管(SWNTs)自组装成束状晶体(Journet6644)。此外,碳纳米管还可以通过各种方法合成和自组装,如DNA介导的自组装、纳米颗粒辅助对齐、化学自组装和电寻址功能化(Tulevski2007)。这些方法已被用于制造大面积纳米结构阵列、高密度集成和自立网络(Tulevski2007)。还可以使用98%的半导体碳纳米管网络溶液,该溶液通过密度梯度超离心方法从金属纳米管中分离出来(Chen2014)。将基板浸入溶液中,然后用去离子水冲洗并用N2气枪吹干,留下均匀的碳网络(Chen2014)。

参考文献

Journet6644: Journet, Catherine, et al. "Large-scale production of single-walled carbon nanotubes by the electric-arc technique." nature 388.6644 (1997): 756-758.

Tulevski2007: Tulevski, George S., et al. "Chemically assisted directed assembly of carbon nanotubes for the fabrication of large-scale device arrays." Journal of the American Chemical Society 129.39 (2007): 11964-11968.

Chen2014: Chen, Haitian, et al. "Large-scale complementary macroelectronics using hybrid integration of carbon nanotubes and IGZO thin-film transistors." Nature communications 5.1 (2014): 4097.

最新更新

版本4移除了langchain包,因为它不再支持序列化。这也简化了软件包,特别是提示部分。Langchain仍然可以使用,但不是必需的。你可以使用langchain中的任何LLMs,但需要使用LangchainLLMModel类来包装模型。

安装

使用pip安装:

pip install paper-qa

你需要有一个LLM来使用paper-qa。你可以使用OpenAI、llama.cpp(通过服务器)或langchain中的任何LLMs。只要你设置了OpenAI API密钥(export OPENAI_API_KEY=sk-...),OpenAI就可以直接使用。其他LLMs的使用说明见下文。

使用方法

要使用paper-qa,你需要有一个路径/文件/URL列表(有效扩展名包括:.pdf, .txt)。然后你可以使用Docs类来添加文档并进行查询。Docs会尝试从文件内容中猜测引用格式,但你也可以自己提供。

from paperqa import Docs my_docs = ... # 获取路径列表 docs = Docs() for d in my_docs: docs.add(d) answer = docs.query( "双特异性抗体制造面临哪些独特的挑战?" ) print(answer.formatted_answer)

answer对象具有以下属性:formatted_answeranswer(仅答案)、questioncontext(用于回答的段落摘要)。

异步

paper-qa被设计为异步使用。同步API只是异步的包装器。以下是方法及其异步等效项:

同步异步
Docs.addDocs.aadd
Docs.add_fileDocs.aadd_file
Docs.add_urlDocs.aadd_url
Docs.get_evidenceDocs.aget_evidence
Docs.queryDocs.aquery

同步版本只是在循环中调用异步版本。大多数现代Python环境原生支持异步(包括Jupyter笔记本!)。因此,你可以在Jupyter笔记本中这样做:

from paperqa import Docs my_docs = ... # 获取路径列表 docs = Docs() for d in my_docs: await docs.aadd(d) answer = await docs.aquery( "双特异性抗体制造面临哪些独特的挑战?" )

添加文档

add将从路径添加。你也可以使用add_file(需要一个文件对象)或add_url来处理其他来源。

选择模型

默认情况下,它使用OpenAI模型,结合了gpt-4o-mini(用于重新排序和摘要步骤,summary_llm参数)和gpt-4-turbo(用于回答步骤,llm参数)。你可以调整这个设置:

docs = Docs(llm="gpt-4o-mini", summary_llm="gpt-4o")

你可以通过指定Anthropic客户端来使用Anthropic模型:

from paperqa import Docs from anthropic import AsyncAnthropic docs = Docs( llm="claude-3-5-sonnet-20240620", summary_llm="claude-3-5-sonnet-20240620", client=AsyncAnthropic(), )

或者你可以使用langchain中可用的任何其他模型:

from paperqa import Docs from langchain_community.chat_models import ChatAnthropic docs = Docs(llm="langchain", client=ChatAnthropic())

注意,我们将模型分为包装器和client,这里的clientChatAnthropic。这是因为client存储了不可序列化的部分,而langchain LLMs有时只能序列化/序列化。paper-qa的Docs必须始终可序列化。因此,我们将模型分为两部分。

import pickle docs = Docs(llm="langchain", client=ChatAnthropic()) model_str = pickle.dumps(docs) docs = pickle.loads(model_str) # 但你必须在加载后设置客户端 docs.set_client(ChatAnthropic())

我们还支持使用Anyscale来利用托管的开源模型。要使用它,你只需设置ANYSCALE_API_KEYANYSCALE_BASE_URL环境变量,或使用从Anyscale初始化的OpenAI客户端,并提供api_keybase_url参数。

本地托管

你可以使用llama.cpp作为LLM。请注意,你应该使用相对较大的模型,因为paper-qa需要遵循很多指令。7B模型的性能不会很好。

最简单的设置方法是下载一个llama文件并用-cb -np 4 -a my-llm-model --embedding执行它,这将启用连续批处理和嵌入。

from paperqa import Docs, LlamaEmbeddingModel from openai import AsyncOpenAI # 启动llama.cpp客户端 local_client = AsyncOpenAI( base_url="http://localhost:8080/v1", api_key="sk-no-key-required" ) docs = Docs( client=local_client, docs_index=NumpyVectorStore(embedding_model=LlamaEmbeddingModel()), texts_index=NumpyVectorStore(embedding_model=LlamaEmbeddingModel()), llm_model=OpenAILLMModel( config=dict( model="my-llm-model", temperature=0.1, frequency_penalty=1.5, max_tokens=512 ) ), )

更改嵌入模型

paper-qa默认使用OpenAI(text-embedding-3-small)嵌入,但对向量存储和嵌入选择都有灵活的选项。更改嵌入的最简单方法是通过Docs对象构造函数的embedding参数:

from paperqa import Docs docs = Docs(embedding="text-embedding-3-large")

embedding接受:

  • 任何OpenAI嵌入模型名称
  • VoyageAI模型名称(如果安装了voyageai并设置了VOYAGE_API_KEY可用)
  • "sentence-transformers"使用Sentence Transformersmulti-qa-MiniLM-L6-cos-v1
  • "hybrid-<model_name>",例如"hybrid-text-embedding-3-small"使用混合稀疏关键词(基于令牌模数嵌入)和密集向量嵌入,任何OpenAI或VoyageAI模型都可以用作密集模型名称
  • "sparse"仅使用稀疏关键词嵌入

对于更深入的嵌入自定义,可以单独构建嵌入模型和向量存储,然后传递给Docs对象。嵌入模型用于创建paper-qa的文档引用嵌入向量索引(docs_index参数)以及全文嵌入向量(texts_index参数)。在创建新的Docs对象时,可以将它们都指定为参数。你可以使用任何实现paper-qa的EmbeddingModel类的嵌入模型。例如,使用text-embedding-3-large

from paperqa import Docs, NumpyVectorStore, OpenAIEmbeddingModel docs = Docs( docs_index=NumpyVectorStore( embedding_model=OpenAIEmbeddingModel(name="text-embedding-3-large") ), texts_index=NumpyVectorStore( embedding_model=OpenAIEmbeddingModel(name="text-embedding-3-large") ), )

请注意,嵌入模型被指定为paper-qa的VectorStore基类的属性。NumpyVectorStore是最好的起点,它是一个简单的内存存储,没有索引。如果需要大于内存的向量存储,你可以这样使用LangchainVectorStore

from langchain_community.vectorstores.faiss import FAISS from langchain_openai import OpenAIEmbeddings from paperqa import Docs, LangchainVectorStore docs = Docs( docs_index=LangchainVectorStore(cls=FAISS, embedding_model=OpenAIEmbeddings()), texts_index=LangchainVectorStore(cls=FAISS, embedding_model=OpenAIEmbeddings()), )

我们支持本地langchain嵌入模型和SentenceTransformer模型。例如:

from paperqa import Docs, SentenceTransformerEmbeddingModel from openai import AsyncOpenAI # 启动llama.cpp客户端 local_client = AsyncOpenAI( base_url="http://localhost:8080/v1", api_key="sk-no-key-required" ) docs = Docs( client=local_client, docs_index=NumpyVectorStore(embedding_model=SentenceTransformerEmbeddingModel()), texts_index=NumpyVectorStore(embedding_model=SentenceTransformerEmbeddingModel()), llm_model=OpenAILLMModel( config=dict( model="my-llm-model", temperature=0.1, frequency_penalty=1.5, max_tokens=512 ) ), )

我们还支持混合关键词(稀疏令牌模数向量)和密集嵌入向量。它们可以这样指定:

from paperqa import Docs, HybridEmbeddingModel, SparseEmbeddingModel, NumpyVectorStore model = HybridEmbeddingModel(models=[OpenAIEmbeddingModel(), SparseEmbeddingModel()]) docs = Docs( docs_index=NumpyVectorStore(embedding_model=model), texts_index=NumpyVectorStore(embedding_model=model), )

稀疏嵌入(关键词)模型默认有256个维度,但可以通过ndim参数指定。

调整源数量

你可以调整源(文本段落)的数量以减少令牌使用或添加更多上下文。k指的是最相关和多样化(可能来自不同源)的前k个段落。每个段落都会被发送给LLM进行总结,或确定是否无关。在此步骤之后,应用max_sources限制,以便最终答案能够适应LLM上下文窗口。因此,k > max_sources,而max_sources是最终答案中使用的源数量。

docs.query( "双特异性抗体特有的制造挑战是什么?", k=5, max_sources=2, )

使用代码或HTML

你不需要使用论文 - 你可以使用代码或原始HTML。请注意,这个工具专注于回答问题,所以它在编写代码方面表现不佳。需要注意的是,该工具无法从代码中推断引用,所以你需要自己提供它们。

import glob source_files = glob.glob("**/*.js") docs = Docs() for f in source_files: # 这假设代码中的文件名是唯一的 docs.add(f, citation="文件 " + os.path.name(f), docname=os.path.name(f)) answer = docs.query("页眉中的搜索栏在哪里定义?") print(answer)

使用外部数据库/向量数据库和缓存

你可能想在外部数据库或文件中缓存解析的文本和嵌入。然后你可以直接从这些构建Docs对象:

docs = Docs() for ... in my_docs: doc = Doc(docname=..., citation=..., dockey=..., citation=...) texts = [Text(text=..., name=..., doc=doc) for ... in my_texts] docs.add_texts(texts, doc)

如果你想使用外部向量存储,也可以通过langchain直接实现。例如,使用langchain的FAISS向量存储:

from paperqa import LangchainVectorStore, Docs from langchain_community.vector_store import FAISS from langchain_openai import OpenAIEmbeddings docs = Docs( texts_index=LangchainVectorStore(cls=FAISS, embedding_model=OpenAIEmbeddings()), docs_index=LangchainVectorStore(cls=FAISS, embedding_model=OpenAIEmbeddings()), )

我从哪里获取论文?

这是一个很好的问题!最好的方法可能是下载你认为有助于回答问题的论文的PDF,然后从那里开始。

Zotero

如果你使用Zotero来组织你的个人参考文献,你可以使用paperqa.contrib.ZoteroDB从你的库中查询论文,它依赖于pyzotero

安装pyzotero以使用此功能:

pip install pyzotero

首先,请注意paperqa解析论文的PDF以存储在数据库中,所以所有相关论文都应该在你的数据库中存储PDF。你可以让Zotero自动执行此操作,方法是高亮显示你想检索的参考文献,右键单击,然后选择"查找可用的PDF"。你也可以手动将PDF拖放到每个参考文献上。

要下载论文,你需要获取你账户的API密钥。

  1. 获取您的图书馆ID,并将其设置为环境变量 ZOTERO_USER_ID
    • 对于个人图书馆,该ID可在此处找到,位于"您在API调用中使用的userID为XXXXXX"部分。
    • 对于群组图书馆,请访问您的群组页面 https://www.zotero.org/groups/groupname,将鼠标悬停在设置链接上。ID是/groups/后的整数。(感谢pyzotero提供的提示!)
  2. 此处创建一个新的API密钥,并将其设置为环境变量 ZOTERO_API_KEY
    • 该密钥需要对图书馆有读取权限。

有了这些,我们就可以从我们的图书馆下载论文并将它们添加到 paperqa 中:

from paperqa.contrib import ZoteroDB docs = paperqa.Docs() zotero = ZoteroDB(library_type="user") # 如果是群组图书馆,则为"group" for item in zotero.iterate(limit=20): if item.num_pages > 30: continue # 跳过长篇论文 docs.add(item.pdf, docname=item.key)

这将下载Zotero数据库中的前20篇论文并将它们添加到 Docs 对象中。

我们还可以对Zotero图书馆进行特定查询并遍历结果:

for item in zotero.iterate( q="large language models", qmode="everything", sort="date", direction="desc", limit=100, ): print("正在添加", item.title) docs.add(item.pdf, docname=item.key)

您可以在IPython中输入 zotero.iterate? 以了解更多关于搜索语法的信息。

论文抓取器

如果您想搜索自己收藏之外的论文,我发现了一个名为paper-scraper的无关项目,看起来可能会有帮助。但请注意,该项目似乎使用了一些可能违反出版商权利或处于法律灰色地带的抓取工具。

keyword_search = "bispecific antibody manufacture" papers = paperscraper.search_papers(keyword_search) docs = paperqa.Docs() for path, data in papers.items(): try: docs.add(path) except ValueError as e: # 有时如果PDF未下载或无法读取会发生这种情况 print("无法读取", path, e) answer = docs.query( "双特异性抗体制造有哪些独特的挑战?" ) print(answer)

PDF阅读选项

默认情况下使用PyPDF,因为它是纯Python实现且易于安装。为了更快的PDF阅读,paper-qa会检测并使用PymuPDF (fitz)

pip install pymupdf

回调工厂

要在LLM完成的每个块上执行函数,您需要提供一个函数,该函数在被调用时会根据步骤名称生成要在每个块上执行的函数列表。例如,要获得完成内容的打字机视图,您可以这样做:

def make_typewriter(step_name): def typewriter(chunk): print(chunk, end="") return [typewriter] # <- 注意这是一个函数列表 ... docs.query( "双特异性抗体制造有哪些独特的挑战?", get_callbacks=make_typewriter, )

缓存嵌入

通常,无论您使用什么向量存储,当您pickle一个 Docs 时,嵌入都会被缓存。有关更明确管理它们的详细信息,请参见上文。

自定义提示

您可以使用 PromptCollection 类自定义任何提示。例如,如果您想更改问题的提示,可以这样做:

from paperqa import Docs, Answer, PromptCollection my_qaprompt = ( "回答问题'{question}' " "如果有帮助,请使用下面的上下文。" "您可以使用键来引用上下文 " "例如(Example2012)。" "如果上下文不足,请写一首诗 " "描述您无法回答的情况。\n\n" "上下文:{context}\n\n" ) prompts = PromptCollection(qa=my_qaprompt) docs = Docs(prompts=prompts)

前置和后置提示

按照上面的语法,您还可以包含在查询之前和之后执行的提示。例如,您可以使用它来对答案进行评论。

常见问题

这与LlamaIndex有何不同?

它并没有太大的不同!这类似于LlamaIndex中的树响应方法。我只是包含了一些我认为有用的提示,能提供页码/行号的阅读器,并专注于一个任务 - 用引用源回答技术问题。

这与LangChain有何不同?

LangChain在检索器方面做了一些很棒的工作,你可以说这是一个基于LLM重新排序和上下文摘要的检索器的例子。

我可以保存或加载吗?

Docs 类可以被pickle和unpickle。如果您想保存文档的嵌入,然后稍后加载它们,这会很有用。

import pickle # 保存 with open("my_docs.pkl", "wb") as f: pickle.dump(docs, f) # 加载 with open("my_docs.pkl", "rb") as f: docs = pickle.load(f) docs.set_client() # 默认使用OpenAI

编辑推荐精选

Vora

Vora

免费创建高清无水印Sora视频

Vora是一个免费创建高清无水印Sora视频的AI工具

Refly.AI

Refly.AI

最适合小白的AI自动化工作流平台

无需编码,轻松生成可复用、可变现的AI自动化工作流

酷表ChatExcel

酷表ChatExcel

大模型驱动的Excel数据处理工具

基于大模型交互的表格处理系统,允许用户通过对话方式完成数据整理和可视化分析。系统采用机器学习算法解析用户指令,自动执行排序、公式计算和数据透视等操作,支持多种文件格式导入导出。数据处理响应速度保持在0.8秒以内,支持超过100万行数据的即时分析。

AI工具酷表ChatExcelAI智能客服AI营销产品使用教程
TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
AIWritePaper论文写作

AIWritePaper论文写作

AI论文写作指导平台

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

AI辅助写作AI工具AI论文工具论文写作智能生成大纲数据安全AI助手热门
博思AIPPT

博思AIPPT

AI一键生成PPT,就用博思AIPPT!

博思AIPPT,新一代的AI生成PPT平台,支持智能生成PPT、AI美化PPT、文本&链接生成PPT、导入Word/PDF/Markdown文档生成PPT等,内置海量精美PPT模板,涵盖商务、教育、科技等不同风格,同时针对每个页面提供多种版式,一键自适应切换,完美适配各种办公场景。

AI办公办公工具AI工具博思AIPPTAI生成PPT智能排版海量精品模板AI创作热门
潮际好麦

潮际好麦

AI赋能电商视觉革命,一站式智能商拍平台

潮际好麦深耕服装行业,是国内AI试衣效果最好的软件。使用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。

iTerms

iTerms

企业专属的AI法律顾问

iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。

SimilarWeb流量提升

SimilarWeb流量提升

稳定高效的流量提升解决方案,助力品牌曝光

稳定高效的流量提升解决方案,助力品牌曝光

Sora2视频免费生成

Sora2视频免费生成

最新版Sora2模型免费使用,一键生成无水印视频

最新版Sora2模型免费使用,一键生成无水印视频

下拉加载更多