PaperQA2 est un package pour effectuer une génération augmentée (RAG) de récupération à haute performance sur les PDF ou les fichiers texte, en mettant l'accent sur la littérature scientifique. Voir notre récent article de 2024 pour voir des exemples de performance surhumaine de PaperQA2 dans des tâches scientifiques comme la réponse aux questions, le résumé et la détection de contradiction.
ask manuellementDans cet exemple, nous prenons un dossier de PDF de document de recherche, obtenons comme par magie leurs métadonnées - y compris les décomptes de citation avec un contrôle de rétraction, puis analyser et cache les PDF dans un index de recherche en texte complet, et enfin répondre à la question de l'utilisateur avec un agent LLM.
pip install paper-qa
cd my_papers
pqa ask ' How can carbon nanotubes be manufactured at a large scale? 'Question: Quelqu'un a-t-il conçu des réseaux de neurones qui calculent-ils des protéines ou de l'ADN?
L'affirmation selon laquelle les réseaux de neurones ont été conçus pour calculer avec l'ADN est soutenu par plusieurs sources. Les travaux de Qian, Winfree et Bruck démontrent l'utilisation de cascades de déplacement des brins d'ADN pour construire des composants de réseau neuronal, tels que les neurones artificiels et les souvenirs associatifs, en utilisant un système basé sur l'ADN (Pages de données Qian2011 1-2, Qian2011 Pages de flèche QIAN2011 54-56). Cette recherche comprend la mise en œuvre d'une porte XOR 3 bits et d'une mémoire associative à quatre neurons, présentant le potentiel de l'ADN pour le calcul du réseau neuronal. De plus, l'application des techniques d'apprentissage en profondeur à la génomique, qui implique le calcul avec des séquences d'ADN, est bien documentée. Des études ont appliqué des réseaux de neurones convolutionnels (CNN) pour prédire les caractéristiques génomiques telles que la liaison au facteur de transcription et l'accessibilité de l'ADN (pages Eraslan2019Dep 4-5, Eraslan2019Dep Pages 5-6). Ces modèles exploitent les séquences d'ADN en tant que données d'entrée, en utilisant efficacement les réseaux de neurones pour calculer avec l'ADN. Bien que les extraits fournis ne mentionnent pas explicitement le calcul de réseaux neuronaux à base de protéines, ils mettent en évidence l'utilisation de réseaux de neurones dans des tâches liées aux séquences protéiques, telles que la prévision de la liaison à la protéine ADN (Pages de convection Zeng2016 1-2). Cependant, l'objectif principal reste sur le calcul basé sur l'ADN.
PaperQA2 est conçu pour être le meilleur modèle de chiffon agentique pour travailler avec des articles scientifiques. Voici quelques fonctionnalités:
Par défaut, il utilise des incorporations et des modèles OpenAI avec une base de données vectorielle Numpy pour intégrer et rechercher des documents. Cependant, vous pouvez facilement utiliser d'autres modèles ou intégres open source à source fermée (voir les détails ci-dessous).
PaperQA2 dépend de certaines bibliothèques / API impressionnantes qui rendent notre référentiel possible. En voici quelques-uns dans aucun ordre particulier:
Nous travaillons dur sur les mises à niveau fondamentales depuis un certain temps et avons surtout suivi Semver. Cela signifie que nous avons incrémenté le principal numéro de version à chaque changement de rupture. Cela nous amène au numéro de version actuel de la version principale V5. Alors pourquoi appeler le repo est-il maintenant appelé PaperQA2? Nous voulions remarquer le fait que nous avons dépassé la performance humaine sur de nombreuses mesures importantes. Nous appelons donc arbitrairement la version 5 et le PaperQA2 vers le jour, et les versions avant PaperQA1 pour désigner le changement significatif de performance. Nous reconnaissons que nous sommes mis au défi de nommer et de compter à Futurehouse, nous nous réservons donc le droit à tout moment pour changer arbitrairement le nom en PaperCrow.
Version 5 ajoutée:
pqaDocs Notez que les objets Docs marinés à partir des versions antérieures de PaperQA sont incompatibles avec la version 5 et devront être reconstruits. De plus, notre version Python minimale a été augmentée à Python 3.11.
Pour comprendre PaperQA2, commençons par les pièces de l'algorithme sous-jacent. Le flux de travail par défaut de PaperQA2 est le suivant:
| Phase | Actions PaperQA2 |
|---|---|
| 1. Recherche de papier | - Obtenez des documents candidats à partir de la requête de mots clés générée par LLM |
| - Chunk, intégrer et ajouter des papiers candidats à l'état | |
| 2. Rassembler des preuves | - Intégrer la requête dans le vecteur |
| - Classer les morceaux de document K TOP K à l'état actuel | |
| - Créer un résumé de chaque morceau dans le contexte de la requête actuelle | |
| - Utilisez LLM pour re-sonner et sélectionner les résumés les plus pertinents | |
| 3. Générez la réponse | - Mettez les meilleurs résumés dans une invite avec le contexte |
| - générer une réponse avec une invite |
Les outils peuvent être invoqués dans n'importe quel ordre par un agent linguistique. Par exemple, un agent LLM peut effectuer une recherche étroite et large, ou en utilisant un phrasé différent pour l'étape de preuve de la collecte de l'étape de réponse de génération.
Pour une configuration de non-développement, installez PaperQA2 (AKA version 5) de PYPI. Remarque La version 5 nécessite Python 3.11+.
pip install paper-qa > =5Pour la configuration du développement, veuillez vous référer au fichier contribution.md.
PaperQa2 utilise un LLM pour fonctionner, vous devrez donc soit définir une variable d'environnement de clé API appropriée (IE export OPENAI_API_KEY=sk-... ) ou configurer un serveur LLM open source (c'est-à-dire en utilisant LlamaFile. Tout modèle compatible Litellm peut être configuré pour utiliser avec PaperQA2.
Si vous devez indexer un grand ensemble de papiers (100+), vous voudrez probablement une clé API pour CrossRef et Semantic Scholar, ce qui vous permettra d'éviter d'atteindre les limites de taux publics en utilisant ces services de métadonnées. Ceux-ci peuvent être exportés sous forme de variables CROSSREF_API_KEY et SEMANTIC_SCHOLAR_API_KEY .
Le moyen le plus rapide de tester PaperQA2 est via la CLI. Accédez d'abord à un répertoire avec certains papiers et utilisez la CLI pqa :
$ pqa ask ' What manufacturing challenges are unique to bispecific antibodies? 'Vous verrez PaperQA2 index vos fichiers PDF locaux, rassemblant les métadonnées nécessaires pour chacun d'elles (en utilisant Crossref et Semantic Scholar), recherchez cet index, puis divisez les fichiers en contextes de preuves ouverts, les classez et générez finalement une réponse. La prochaine fois que ce répertoire sera interrogé, votre index sera déjà construit (sauf pour toutes les différences détectées, comme de nouveaux papiers ajoutés), donc il sautera les étapes d'indexation et de section.
Toutes les réponses antérieures seront indexées et stockées, vous pouvez les afficher en interrogeant via la sous-commande search , ou y accéder vous-même dans votre répertoire PQA_HOME , qui par défaut ~/.pqa/ .
$ pqa search -i ' answers ' ' antibodies ' PaperQA2 est hautement configurable, lorsqu'il s'exécute à partir de la ligne de commande, pqa --help affiche toutes les options et les courtes descriptions. Par exemple pour fonctionner avec une température plus élevée:
$ pqa --temperature 0.5 ask ' What manufacturing challenges are unique to bispecific antibodies? ' Vous pouvez afficher tous les paramètres avec pqa view . Une autre chose utile est de passer à d'autres paramètres de modèle - par exemple fast est un paramètre qui répond plus rapidement et vous pouvez le voir avec pqa -s fast view
Peut-être avez-vous de nouveaux paramètres que vous souhaitez enregistrer? Tu peux faire ça avec
pqa -s my_new_settings --temperature 0.5 --llm foo-bar-5 saveEt puis vous pouvez l'utiliser avec
pqa -s my_new_settings ask ' What manufacturing challenges are unique to bispecific antibodies? ' Si vous exécutez pqa avec une commande qui nécessite une nouvelle indexation, disons que si vous modifiez le chunk_size par défaut, un nouvel index sera automatiquement créé pour vous.
pqa --parsing.chunk_size 5000 ask ' What manufacturing challenges are unique to bispecific antibodies? ' Vous pouvez également utiliser pqa pour effectuer la recherche en texte intégral avec l'utilisation de LLMS Affichage de la commande de recherche. Par exemple, enregistrons l'index d'un répertoire et donnons-lui un nom:
pqa -i nanomaterials indexMaintenant, je peux rechercher des articles sur les thermoélectriques:
pqa -i nanomaterials search thermoelectricsou je peux utiliser la demande normale
pqa -i nanomaterials ask ' Are there nm scale features in thermoelectric materials? 'La CLI et le module ont tous deux des paramètres préconfigurés en fonction des performances antérieures et de nos publications, ils peuvent être invoqués comme suit:
pqa --settings < setting name > ask ' Are there nm scale features in thermoelectric materials? ' Dans paperqa/configs nous regroupons les paramètres utiles connus:
| Nom de réglage | Description |
|---|---|
| High_quality | Requête très performante, relativement coûteuse (en raison de evidence_k = 15) à l'aide d'un agent ToolSelector . |
| rapide | Définition pour obtenir des réponses à moindre coût et rapidement. |
| wikicrow | Établissement pour imiter la rédaction de l'article Wikipedia utilisé dans notre publication Wikicrow. |
| s'accumuler | En définissant pour trouver des contradictions dans les articles, votre requête devrait être une affirmation qui doit être signalée comme une contradiction (ou non). |
| déboguer | Définition utile uniquement pour le débogage, mais pas dans aucune application réelle au-delà du débogage. |
| tier1_limits | Paramètres qui correspondent aux limites de taux OpenAI pour chaque niveau, vous pouvez utiliser tier<1-5>_limits pour spécifier le niveau. |
Si vous atteignez des limites de taux, disons avec le plan OpenAI Tier 1, vous pouvez les ajouter dans PaperQA2. Pour chaque niveau Openai, un paramètre prédéfini existe pour limiter l'utilisation.
pqa --settings ' tier1_limits ' ask ' Are there nm scale features in thermoelectric materials? 'Cela limitera votre système à utiliser le Tier1_limits et ralentira vos requêtes pour s'adapter.
Vous pouvez également les spécifier manuellement avec toute chaîne de limite de taux qui correspond à la spécification dans le module Limits:
pqa --summary_llm_config ' {"rate_limit": {"gpt-4o-2024-08-06": "30000 per 1 minute"}} ' ask ' Are there nm scale features in thermoelectric materials? ' Ou en ajoutant dans un objet Settings , si vous appelez impérativement:
from paperqa import Settings , ask
answer = ask (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = Settings (
llm_config = { "rate_limit" : { "gpt-4o-2024-08-06" : "30000 per 1 minute" }},
summary_llm_config = { "rate_limit" : { "gpt-4o-2024-08-06" : "30000 per 1 minute" }},
),
)Le flux de travail complet de PaperQA2 est accessible via Python directement:
from paperqa import Settings , ask
answer = ask (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = Settings ( temperature = 0.5 , paper_directory = "my_papers" ),
)Veuillez consulter nos documents d'installation pour installer le package à partir de PYPI.
ask manuellement L'objet de réponse a les attributs suivants: formatted_answer , answer (réponse seul), question et context (les résumés des passages trouvés pour la réponse). ask utilisera l'outil SearchPapers , qui interrogera un index local des fichiers, vous pouvez spécifier cet emplacement via l'objet Settings :
from paperqa import Settings , ask
answer = ask (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = Settings ( temperature = 0.5 , paper_directory = "my_papers" ),
) ask est juste un emballage de commodité autour du vrai point d'entrée, qui peut être accessible si vous souhaitez exécuter des charges de travail asynchrones simultanées:
from paperqa import Settings , agent_query , QueryRequest
answer = await agent_query (
QueryRequest (
query = "What manufacturing challenges are unique to bispecific antibodies?" ,
settings = Settings ( temperature = 0.5 , paper_directory = "my_papers" ),
)
) L'agent par défaut utilisera un agent basé sur LLM, mais vous pouvez également spécifier un "fake" agent pour utiliser un chemin d'appel codé en dur -> Recueillir des preuves -> Réponse pour réduire l'utilisation de jetons.
Si vous préférez un contrôle à grain fin et que vous souhaitez ajouter vous-même des objets à l'objet DOCS (plutôt que d'utiliser l'outil de recherche), l'interface d'objet Docs existant peut être utilisée:
from paperqa import Docs , Settings
# valid extensions include .pdf, .txt, and .html
doc_paths = ( "myfile.pdf" , "myotherfile.pdf" )
docs = Docs ()
for doc in doc_paths :
docs . add ( doc )
settings = Settings ()
settings . llm = "claude-3-5-sonnet-20240620"
settings . answer . answer_max_sources = 3
answer = docs . query (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = settings ,
)
print ( answer . formatted_answer ) PaperQA2 est écrit pour être utilisé de manière asynchrone. L'API synchrone est juste un emballage autour de l'async. Voici les méthodes et leurs équivalents async :
| Synchronisation | Asynchrone |
|---|---|
Docs.add | Docs.aadd |
Docs.add_file | Docs.aadd_file |
Docs.add_url | Docs.aadd_url |
Docs.get_evidence | Docs.aget_evidence |
Docs.query | Docs.aquery |
La version synchrone appelle simplement la version asynchrone dans une boucle. La plupart des environnements Python modernes prennent en charge async Native (y compris les cahiers Jupyter!). Vous pouvez donc le faire dans un cahier Jupyter:
import asyncio
from paperqa import Docs
async def main () -> None :
docs = Docs ()
# valid extensions include .pdf, .txt, and .html
for doc in ( "myfile.pdf" , "myotherfile.pdf" ):
await docs . aadd ( doc )
answer = await docs . aquery (
"What manufacturing challenges are unique to bispecific antibodies?"
)
print ( answer . formatted_answer )
asyncio . run ( main ()) Par défaut, il utilise des modèles OpenAI avec gpt-4o-2024-08-06 pour l'étape de relance et de résumé, le paramètre summary_llm , et pour l'étape de réponse, le paramètre llm . Vous pouvez ajuster cela facilement:
from paperqa import Settings , ask
answer = ask (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = Settings (
llm = "gpt-4o-mini" , summary_llm = "gpt-4o-mini" , paper_directory = "my_papers"
),
) Vous pouvez utiliser anthropic ou tout autre modèle pris en charge par litellm :
from paperqa import Settings , ask
answer = ask (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = Settings (
llm = "claude-3-5-sonnet-20240620" , summary_llm = "claude-3-5-sonnet-20240620"
),
)Vous pouvez utiliser llama.cpp pour être le LLM. Notez que vous devriez utiliser des modèles relativement importants, car PaperQA2 nécessite de suivre de nombreuses instructions. Vous n'obtiendrez pas de bonnes performances avec les modèles 7B.
La façon la plus simple de se configurer est de télécharger un fichier lama et de l'exécuter avec -cb -np 4 -a my-llm-model --embedding qui permettra un lot et des incorporations continues.
from paperqa import Settings , ask
local_llm_config = dict (
model_list = [
dict (
model_name = "my_llm_model" ,
litellm_params = dict (
model = "my-llm-model" ,
api_base = "http://localhost:8080/v1" ,
api_key = "sk-no-key-required" ,
temperature = 0.1 ,
frequency_penalty = 1.5 ,
max_tokens = 512 ,
),
)
]
)
answer = ask (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = Settings (
llm = "my-llm-model" ,
llm_config = local_llm_config ,
summary_llm = "my-llm-model" ,
summary_llm_config = local_llm_config ,
),
) Les modèles hébergés avec ollama sont également pris en charge. Pour exécuter l'exemple ci-dessous, assurez-vous que vous avez téléchargé LLAMA3.2 et MXBAI-EMBED-LANG via Olllama.
from paperqa import Settings , ask
local_llm_config = {
"model_list" : [
{
"model_name" : "ollama/llama3.2" ,
"litellm_params" : {
"model" : "ollama/llama3.2" ,
"api_base" : "http://localhost:11434" ,
},
}
]
}
answer = ask (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = Settings (
llm = "ollama/llama3.2" ,
llm_config = local_llm_config ,
summary_llm = "ollama/llama3.2" ,
summary_llm_config = local_llm_config ,
embedding = "ollama/mxbai-embed-large" ,
),
) PaperQA2 est par défaut en utilisant des intégres OpenAI ( text-embedding-3-small ), mais a des options flexibles pour les magasins vectoriels et les choix d'intégration. La façon la plus simple de modifier une intégration est via l'argument d' embedding dans le constructeur d'objets Settings :
from paperqa import Settings , ask
answer = ask (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = Settings ( embedding = "text-embedding-3-large" ),
) embedding accepte tout nom de modèle d'intégration pris en charge par Litellm. PaperQA2 prend également en charge une entrée d'intégration de "hybrid-<model_name>" IE "hybrid-text-embedding-3-small" pour utiliser un mot-clé hybride clairsemé (basé sur une incorporation de module de jeton) et une intégration vectorielle dense, où tout modèle litellm peut être utilisé dans le nom du modèle dense. "sparse" peut être utilisé pour utiliser un mot-clé clairsemé intégrant uniquement.
Les modèles d'intégration sont utilisés pour créer l'index de PaperQA2 des vecteurs d'intégration en texte intégral (argument texts_index ). Le modèle d'intégration peut être spécifié comme un paramètre lorsque vous ajoutez de nouveaux articles à l'objet Docs :
from paperqa import Docs , Settings
docs = Docs ()
for doc in ( "myfile.pdf" , "myotherfile.pdf" ):
docs . add ( doc , settings = Settings ( embedding = "text-embedding-large-3" )) Notez que PaperQA2 utilise Numpy comme magasin de vecteur dense. Sa conception de l'utilisation d'une recherche de mots clés réduit initialement le nombre de morceaux nécessaires pour chaque réponse à un nombre relativement petit <1k. Par conséquent, NumpyVectorStore est un bon point de départ, c'est un simple magasin en mémoire, sans index. Cependant, si un magasin vectoriel plus grand que la mémoire est nécessaire, nous manquons actuellement ici.
Les incorporations hybrides peuvent être personnalisées:
from paperqa import (
Docs ,
HybridEmbeddingModel ,
SparseEmbeddingModel ,
LiteLLMEmbeddingModel ,
)
model = HybridEmbeddingModel (
models = [ LiteLLMEmbeddingModel (), SparseEmbeddingModel ( ndim = 1024 )]
)
docs = Docs ()
for doc in ( "myfile.pdf" , "myotherfile.pdf" ):
docs . add ( doc , embedding_model = model ) Les modèles de l'intégration (mot-clé) clairsemées ont par défaut avec 256 dimensions, mais cela peut être spécifié via l'argument ndim .
Vous pouvez utiliser un modèle SentenceTransformerEmbeddingModel si vous installez sentence-transformers , qui est une bibliothèque d'intégration locale avec la prise en charge des modèles HuggingFace et plus encore. Vous pouvez l'installer en ajoutant les extras local .
pip install paper-qa[local] puis préfixer les noms de modèle d'intégration avec st- :
from paperqa import Settings , ask
answer = ask (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = Settings ( embedding = "st-multi-qa-MiniLM-L6-cos-v1" ),
)ou avec un modèle hybride
from paperqa import Settings , ask
answer = ask (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = Settings ( embedding = "hybrid-st-multi-qa-MiniLM-L6-cos-v1" ),
) Vous pouvez ajuster le nombre de sources (passages de texte) pour réduire l'utilisation des jetons ou ajouter plus de contexte. k fait référence aux passages K TOP K les plus pertinents et les plus diversifiés (peut de différentes sources). Chaque passage est envoyé au LLM pour résumer ou déterminer s'il n'est pas pertinent. Après cette étape, une limite de max_sources est appliquée afin que la réponse finale puisse s'intégrer dans la fenêtre de contexte LLM. Ainsi, k > max_sources et max_sources est le nombre de sources utilisées dans la réponse finale.
from paperqa import Settings
settings = Settings ()
settings . answer . answer_max_sources = 3
settings . answer . k = 5
docs . query (
"What manufacturing challenges are unique to bispecific antibodies?" ,
settings = settings ,
)Vous n'avez pas besoin d'utiliser des papiers - vous pouvez utiliser du code ou du HTML brut. Notez que cet outil est axé sur la réponse aux questions, il ne fera donc pas bien d'écriture de code. Une note est que l'outil ne peut pas déduire les citations du code, vous devrez donc les fournir vous-même.
import glob
import os
from paperqa import Docs
source_files = glob . glob ( "**/*.js" )
docs = Docs ()
for f in source_files :
# this assumes the file names are unique in code
docs . add ( f , citation = "File " + os . path . name ( f ), docname = os . path . name ( f ))
answer = docs . query ( "Where is the search bar in the header defined?" )
print ( answer )Vous voudrez peut-être mettre en cache des textes et intégrer des textes dans une base de données ou un fichier externes. Vous pouvez ensuite construire un objet Docs à partir de ceux directement:
from paperqa import Docs , Doc , Text
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 ) Les index seront placés dans le répertoire domestique par défaut. Cela peut être contrôlé via la variable d'environnement PQA_HOME .
Les index sont fabriqués en lisant des fichiers dans les Settings.paper_directory . Par défaut, nous lisons récursivement à partir des sous-répertoires du répertoire papier, sauf si désactivés à l'aide de Settings.index_recursively . Le répertoire papier n'est pas modifié en aucune façon, il est juste lu.
Le processus d'indexation tente de déduire des métadonnées de papier comme le titre et DOI à l'aide de traitement de texte alimenté par LLM. Vous pouvez éviter ce point d'incertitude en utilisant un fichier "manifeste", qui est un CSV contenant trois colonnes (l'ordre n'a pas d'importance):
file_location : chemin relatif au PDF du papier dans le répertoire d'indexdoi : doi du papiertitle : Titre du journalEn fournissant ces informations, nous assurons que les requêtes aux fournisseurs de métadonnées comme CrossRef sont exactes.
Les index de recherche locaux sont construits sur la base d'un hachage de l'objet Settings actuel. Assurez-vous donc de spécifier correctement le paper_directory dans l'objet de votre Settings . En général, il est conseillé de:
import os
from paperqa import Settings
from paperqa . agents . main import agent_query
from paperqa . agents . models import QueryRequest
from paperqa . agents . search import get_directory_index
async def amain ( folder_of_papers : str | os . PathLike ) -> None :
settings = Settings ( paper_directory = folder_of_papers )
# 1. Build the index. Note an index name is autogenerated when unspecified
built_index = await get_directory_index ( settings = settings )
print ( settings . get_index_name ()) # Display the autogenerated index name
print ( await built_index . index_files ) # Display the index contents
# 2. Use the settings as many times as you want with ask
answer_response_1 = await agent_query (
query = QueryRequest (
query = "What is the best way to make a vaccine?" , settings = settings
)
)
answer_response_2 = await agent_query (
query = QueryRequest (
query = "What manufacturing challenges are unique to bispecific antibodies?" ,
settings = settings ,
)
) Dans paperqa/agents/task.py , vous trouverez:
GradablePaperQAEnvironment : un environnement qui peut noter les réponses compte tenu d'une fonction d'évaluation.LitQAv2TaskDataset : un ensemble de données de tâches conçu pour tirer Litqa V2 de l'étreinte et créer un GradablePaperQAEnvironment par questionVoici un exemple de la façon de les utiliser:
import os
from aviary . env import TaskDataset
from ldp . agent import SimpleAgent
from ldp . alg . callbacks import MeanMetricsCallback
from ldp . alg . runners import Evaluator , EvaluatorConfig
from paperqa import QueryRequest , Settings
from paperqa . agents . task import TASK_DATASET_NAME
async def evaluate ( folder_of_litqa_v2_papers : str | os . PathLike ) -> None :
base_query = QueryRequest (
settings = Settings ( paper_directory = folder_of_litqa_v2_papers )
)
dataset = TaskDataset . from_name ( TASK_DATASET_NAME , base_query = base_query )
metrics_callback = MeanMetricsCallback ( eval_dataset = dataset )
evaluator = Evaluator (
config = EvaluatorConfig ( batch_size = 3 ),
agent = SimpleAgent (),
dataset = dataset ,
callbacks = [ metrics_callback ],
)
await evaluator . evaluate ()
print ( metrics_callback . eval_means )L'une des caractéristiques les plus puissantes de PaperQA2 est sa capacité à combiner des données à partir de plusieurs sources de métadonnées. Par exemple, Unpaywall peut fournir un statut d'accès ouvert / des liens directs aux PDF, CrossRef peut fournir un bibtex et le chercheur sémantique peut fournir des licences de citation. Voici une courte démo de la façon de faire ceci:
from paperqa . clients import DocMetadataClient , ALL_CLIENTS
client = DocMetadataClient ( clients = ALL_CLIENTS )
details = await client . query ( title = "Augmenting language models with chemistry tools" )
print ( details . formatted_citation )
# Andres M. Bran, Sam Cox, Oliver Schilter, Carlo Baldassari, Andrew D. White, and Philippe Schwaller.
# Augmenting large language models with chemistry tools. Nature Machine Intelligence,
# 6:525-535, May 2024. URL: https://doi.org/10.1038/s42256-024-00832-8,
# doi:10.1038/s42256-024-00832-8.
# This article has 243 citations and is from a domain leading peer-reviewed journal.
print ( details . citation_count )
# 243
print ( details . license )
# cc-by
print ( details . pdf_url )
# https://www.nature.com/articles/s42256-024-00832-8.pdf Le client.query est destiné à vérifier les correspondances exactes du titre. C'est un peu robuste (comme le boîtier, manquant un mot). Il y a cependant des doublons pour les titres - vous pouvez donc également ajouter des auteurs à désambiguïter. Ou vous pouvez fournir un DOI directement client.query(doi="10.1038/s42256-024-00832-8") .
Si vous faites cela à grande échelle, vous ne voudrez peut-être pas utiliser ALL_CLIENTS (omettez simplement l'argument) et vous pouvez spécifier les champs spécifiques que vous souhaitez accélérer les requêtes. Par exemple:
details = await client . query (
title = "Augmenting large language models with chemistry tools" ,
authors = [ "Andres M. Bran" , "Sam Cox" ],
fields = [ "title" , "doi" ],
)reviendra beaucoup plus rapidement que la première requête et nous serons certains que les auteurs correspondent.
Eh bien, c'est une très bonne question! Il est probablement préférable de simplement télécharger des PDF de papiers qui, selon vous, vous aideront à répondre à votre question et à commencer à partir de là.
Cela fait un moment que nous n'avons pas testé cela - alors faites-nous savoir si cela rencontre des problèmes!
Si vous utilisez Zotero pour organiser votre bibliographie personnelle, vous pouvez utiliser le paperqa.contrib.ZoteroDB pour interroger les articles de votre bibliothèque, qui s'appuie sur Pyzotero.
Installez pyzotero via le zotero Extra pour cette fonction:
pip install paperqa[zotero]Tout d'abord, notez que PaperQA2 analyse les PDF des articles à stocker dans la base de données, de sorte que tous les articles pertinents doivent faire stocker les PDF dans votre base de données. Vous pouvez faire en sorte que Zotero le fasse automatiquement en mettant en évidence les références que vous souhaitez récupérer, cliquer avec le bouton droit et sélectionner "Trouver des PDF disponibles" . Vous pouvez également faire glisser manuellement les PDF sur chaque référence.
Pour télécharger des articles, vous devez obtenir une clé API pour votre compte.
ZOTERO_USER_ID .https://www.zotero.org/groups/groupname et sur le lien des paramètres. L'ID est l'intégralité après / groupes /. ( h / t pyzotero! )ZOTERO_API_KEY .Avec cela, nous pouvons télécharger des papiers à partir de notre bibliothèque et les ajouter à PaperQA2:
from paperqa import Docs
from paperqa . contrib import ZoteroDB
docs = Docs ()
zotero = ZoteroDB ( library_type = "user" ) # "group" if group library
for item in zotero . iterate ( limit = 20 ):
if item . num_pages > 30 :
continue # skip long papers
docs . add ( item . pdf , docname = item . key ) qui téléchargeront les 20 premiers articles de votre base de données Zotero et les ajoutera à l'objet Docs .
Nous pouvons également faire des requêtes spécifiques de notre bibliothèque Zotero et itérer sur les résultats:
for item in zotero . iterate (
q = "large language models" ,
qmode = "everything" ,
sort = "date" ,
direction = "desc" ,
limit = 100 ,
):
print ( "Adding" , item . title )
docs . add ( item . pdf , docname = item . key ) Vous pouvez en savoir plus sur la syntaxe de recherche en tapant zotero.iterate? dans ipython.
Si vous souhaitez rechercher des papiers en dehors de votre propre collection, j'ai trouvé un projet non lié appelé papier-scintigage qui semble aider. Mais méfiez-vous, ce projet semble utiliser des outils de grattage qui peuvent violer les droits de l'éditeur ou être dans une zone de légalité grise.
from paperqa import Docs
keyword_search = "bispecific antibody manufacture"
papers = paperscraper . search_papers ( keyword_search )
docs = Docs ()
for path , data in papers . items ():
try :
docs . add ( path )
except ValueError as e :
# sometimes this happens if PDFs aren't downloaded or readable
print ( "Could not read" , path , e )
answer = docs . query (
"What manufacturing challenges are unique to bispecific antibodies?"
)
print ( answer )Pour exécuter une fonction sur chaque morceau de compléments LLM, vous devez fournir une fonction qui peut être exécutée sur chaque morceau. Par exemple, pour obtenir une vue de machine à écrire des compléments, vous pouvez faire:
def typewriter ( chunk : str ) -> None :
print ( chunk , end = "" )
docs = Docs ()
# add some docs...
docs . query (
"What manufacturing challenges are unique to bispecific antibodies?" ,
callbacks = [ typewriter ],
) En général, les intérêts sont mis en cache lorsque vous pickle un Docs quel que soit le magasin vectoriel que vous utilisez. Donc, tant que vous enregistrez votre objet Docs sous-jacent, vous devriez être en mesure d'éviter de réintégrer vos documents.
Vous pouvez personnaliser l'une des invites à l'aide de paramètres.
from paperqa import Docs , Settings
my_qa_prompt = (
"Answer the question '{question}' n "
"Use the context below if helpful. "
"You can cite the context using the key like (Example2012). "
"If there is insufficient context, write a poem "
"about how you cannot answer. n n "
"Context: {context}"
)
docs = Docs ()
settings = Settings ()
settings . prompts . qa = my_qa_prompt
docs . query ( "Are covid-19 vaccines effective?" , settings = settings )Après la syntaxe ci-dessus, vous pouvez également inclure des invites qui sont exécutées après la requête et avant la requête. Par exemple, vous pouvez l'utiliser pour critiquer la réponse.
En interne à Futurehouse, nous avons un ensemble d'outils légèrement différents. Nous essayons d'obtenir certains d'entre eux, comme la traversée de citation, dans ce dépôt. Cependant, nous avons des API et des licences pour accéder aux documents de recherche que nous ne pouvons pas partager ouvertement. De même, dans les résultats de nos articles de recherche, nous ne commençons pas par les PDF pertinents connus. Notre agent doit les identifier à l'aide de la recherche de mots clés sur tous les articles, plutôt qu'un simple sous-ensemble. Nous alignons progressivement ces deux versions de PaperQA, mais jusqu'à ce qu'il y ait un moyen open-source d'accéder librement aux papiers (même juste des articles open source), vous devrez fournir vous-même des PDF.
Langchain et Llamaindex sont tous deux des cadres pour travailler avec les applications LLM, avec des abstractions conçues pour les flux de travail agentiques et la génération augmentée de récupération.
Au fil du temps, l'équipe PaperQA au fil du temps a choisi de devenir des conducteurs LLM à l'absence de framework, à la place de LLM et sans cadre en plus de Pyndantic pour ses outils. PaperQA se concentre sur les articles scientifiques et leurs métadonnées.
PaperQA peut être réimplémenté à l'aide de Llamaindex ou de Langchain. Par exemple, notre outil GatherEvidence peut être réimplémenté en tant que retriever avec un recommandation et un résumé contextuel basé sur LLM. Il y a un travail similaire avec la méthode de réponse des arbres dans Llamaindex.
La classe Docs peut être marinée et non piquée. Ceci est utile si vous souhaitez enregistrer les intégres des documents, puis les charger plus tard.
import pickle
# save
with open ( "my_docs.pkl" , "wb" ) as f :
pickle . dump ( docs , f )
# load
with open ( "my_docs.pkl" , "rb" ) as f :
docs = pickle . load ( f )Contenu dans les documents / 2024-10-16_litqa2-splits.json5 sont les identifiants de questions (correspondent aux identifiants de questions LitQA2 de Lab-Bench) utilisés dans le train et les divisions d'évaluation, ainsi que les DOI de papier utilisés pour construire le train et l'évaluation des indices de divisions . La fraction de test reste maintenue.
Veuillez lire et citer les articles suivants si vous utilisez ce logiciel:
@article { skarlinski2024language ,
title = { Language agents achieve superhuman synthesis of scientific knowledge } ,
author = {
Michael D. Skarlinski and
Sam Cox and
Jon M. Laurent and
James D. Braza and
Michaela Hinks and
Michael J. Hammerling and
Manvitha Ponnapati and
Samuel G. Rodriques and
Andrew D. White } ,
year = { 2024 } ,
journal = { arXiv preprent arXiv:2409.13740 } ,
url = { https://doi.org/10.48550/arXiv.2409.13740 }
} @article { lala2023paperqa ,
title = { PaperQA: Retrieval-Augmented Generative Agent for Scientific Research } ,
author = {
Jakub Lála and
Odhran O'Donoghue and
Aleksandar Shtedritski and
Sam Cox and
Samuel G. Rodriques and
Andrew D. White } ,
journal = { arXiv preprint arXiv:2312.07559 } ,
year = { 2023 }
}