Skip to content

Instantly share code, notes, and snippets.

@patchy631
Created August 25, 2024 07:35
Show Gist options
  • Save patchy631/853f26eea28b3a77c3c9188094e9126a to your computer and use it in GitHub Desktop.
Save patchy631/853f26eea28b3a77c3c9188094e9126a to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "46f32ff1",
"metadata": {},
"source": [
"# Agnetic RAG"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "d4c06c95-e8b2-4574-b14d-685876aa1c47",
"metadata": {
"height": 47,
"tags": []
},
"outputs": [],
"source": [
"import sys\n",
"import glob\n",
"import nest_asyncio\n",
"from typing import List\n",
"from pathlib import Path\n",
"from IPython.display import Markdown, display\n",
"\n",
"from llama_index.core import PromptTemplate\n",
"from llama_index.core.vector_stores import FilterCondition\n",
"from llama_index.core.vector_stores import MetadataFilters\n",
"from llama_index.core.tools import FunctionTool\n",
"from llama_index.core.tools import QueryEngineTool\n",
"from llama_index.core import DocumentSummaryIndex\n",
"from llama_index.core.node_parser import SentenceSplitter\n",
"from llama_index.core import (\n",
" SummaryIndex,\n",
" VectorStoreIndex,\n",
" SimpleDirectoryReader,\n",
" get_response_synthesizer,\n",
")\n",
"from llama_index.core.query_engine.router_query_engine import RouterQueryEngine\n",
"from llama_index.core.selectors import LLMSingleSelector\n",
"from llama_index.core import Settings\n",
"from llama_index.llms.ollama import Ollama\n",
"from llama_index.embeddings.fastembed import FastEmbedEmbedding\n",
"\n",
"nest_asyncio.apply()"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "e1f6ce56",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d2458f94c1e74561a06ad15ad90571e4",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Fetching 5 files: 0%| | 0/5 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"embed_model = FastEmbedEmbedding(model_name=\"BAAI/bge-small-en-v1.5\")\n",
"\n",
"llm = Ollama(model=\"llama3.1\", request_timeout=360.0)\n",
"# llm = Ollama(model=\"llama3.1\", request_timeout=60.0)\n",
"\n",
"Settings.llm = llm\n",
"Settings.embed_model = embed_model"
]
},
{
"cell_type": "markdown",
"id": "6589123f",
"metadata": {},
"source": [
"### Load Data"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "fbe9326c-d7b3-452b-ae52-12f000157be4",
"metadata": {
"height": 79,
"tags": []
},
"outputs": [],
"source": [
"from llama_index.core import SimpleDirectoryReader\n",
"# load documents\n",
"documents = SimpleDirectoryReader(input_files=[\"/teamspace/studios/this_studio/documents/dspy.pdf\"]).load_data()"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "5451f0a3-d0a6-4b5c-a337-8e1a343ff5f0",
"metadata": {
"height": 64,
"tags": []
},
"outputs": [],
"source": [
"from llama_index.core.node_parser import SentenceSplitter\n",
"splitter = SentenceSplitter(chunk_size=1024)\n",
"nodes = splitter.get_nodes_from_documents(documents)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "e0fe0a9c-1f87-4ae7-a79e-7c3cf9c395ed",
"metadata": {
"height": 30,
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"page_label: 1\n",
"file_name: dspy.pdf\n",
"file_path: /teamspace/studios/this_studio/documents/dspy.pdf\n",
"file_type: application/pdf\n",
"file_size: 460814\n",
"creation_date: 2024-08-25\n",
"last_modified_date: 2024-06-06\n",
"\n",
"Preprint\n",
"DSP Y: C OMPILING DECLARATIVE LANGUAGE\n",
"MODEL CALLS INTO SELF-IMPROVING PIPELINES\n",
"Omar Khattab,1Arnav Singhvi,2\n",
"Paridhi Maheshwari,4Zhiyuan Zhang,1\n",
"Keshav Santhanam,1Sri Vardhamanan,6Saiful Haq,6\n",
"Ashutosh Sharma,6Thomas T. Joshi,7Hanna Moazam,8\n",
"Heather Miller,3,9Matei Zaharia,2Christopher Potts1\n",
"1Stanford University,2UC Berkeley,3Carnegie Mellon University,\n",
"4Amazon Alexa AI,5Dashworks Technologies, Inc.,\n",
"6IIT Bombay,7Calera Capital,8Microsoft,9Two Sigma Investments\n",
"[email protected]\n",
"ABSTRACT\n",
"The ML community is rapidly exploring techniques for prompting language mod-\n",
"els (LMs) and for stacking them into pipelines that solve complex tasks. Un-\n",
"fortunately, existing LM pipelines are typically implemented using hard-coded\n",
"“prompt templates”, i.e. lengthy strings discovered via trial and error. Toward a\n",
"more systematic approach for developing and optimizing LM pipelines, we intro-\n",
"duce DSPy, a programming model that abstracts LM pipelines as text transforma-\n",
"tion graphs , i.e. imperative computation graphs where LMs are invoked through\n",
"declarative modules. DSPy modules are parameterized , meaning they can learn\n",
"(by creating and collecting demonstrations) how to apply compositions of prompt-\n",
"ing, finetuning, augmentation, and reasoning techniques. We design a compiler\n",
"that will optimize any DSPy pipeline to maximize a given metric. We conduct\n",
"two case studies, showing that succinct DSPy programs can express and optimize\n",
"sophisticated LM pipelines that reason about math word problems, tackle multi-\n",
"hop retrieval, answer complex questions, and control agent loops. Within minutes\n",
"of compiling, a few lines of DSPy allow GPT-3.5 andllama2-13b-chat to self-\n",
"bootstrap pipelines that outperform standard few-shot prompting (generally by\n",
"over 25% and 65%, respectively) and pipelines with expert-created demonstra-\n",
"tions (by up to 5–46% and 16–40%, respectively). On top of that, DSPy pro-\n",
"grams compiled to open and relatively small LMs like 770M-parameter T5and\n",
"llama2-13b-chat are competitive with approaches that rely on expert-written\n",
"prompt chains for proprietary GPT-3.5 .\n",
"DSPy is available at https://github.com/stanfordnlp/dspy .\n",
"1 I NTRODUCTION\n",
"Language models (LMs) are enabling researchers to build NLP systems at higher levels of abstrac-\n",
"tion and with lower data requirements than ever before (Bommasani et al., 2021). This is fueling an\n",
"exploding space of “prompting” techniques—and lightweight finetuning techniques—for adapting\n",
"LMs to new tasks (Kojima et al., 2022), eliciting systematic reasoning from them (Wei et al., 2022;\n",
"Wang et al., 2022b), and augmenting them with retrieved sources (Guu et al., 2020; Lazaridou et al.,\n",
"2022; Khattab et al., 2022) or with tools (Yao et al., 2022; Schick et al., 2023). Most of these tech-\n",
"niques are explored in isolation, but interest has been growing in building multi-stage pipelines and\n",
"agents that decompose complex tasks into more manageable calls to LMs in an effort to improve\n",
"performance (Qi et al., 2019; Khattab et al., 2021a; Karpas et al., 2022; Dohan et al., 2022; Khot\n",
"et al., 2022; Khattab et al., 2022; Chen et al., 2022; Pourreza & Rafiei, 2023; Shinn et al., 2023).\n",
"Unfortunately, LMs are known to be sensitive to how they are prompted for each task, and this is\n",
"exacerbated in pipelines where multiple LM calls have to interact effectively. As a result, the LM\n",
"1arXiv:2310.03714v1 [cs.CL] 5 Oct 2023\n"
]
}
],
"source": [
"print(nodes[0].get_content(metadata_mode=\"all\"))"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "d7965cba-67b8-4cca-8e5f-2b0dbc96f6b0",
"metadata": {
"height": 96,
"tags": []
},
"outputs": [],
"source": [
"vector_index = VectorStoreIndex(nodes)\n",
"summary_index = SummaryIndex(nodes)"
]
},
{
"cell_type": "markdown",
"id": "6c392482",
"metadata": {},
"source": [
"### Vector query tool"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "2639e79b-f615-425b-85ea-8a279bb26dd0",
"metadata": {
"height": 623,
"tags": []
},
"outputs": [],
"source": [
"from typing import List\n",
"from llama_index.core.vector_stores import FilterCondition\n",
"from llama_index.core.vector_stores import MetadataFilters\n",
"\n",
"\n",
"def vector_query(\n",
" query: str, \n",
" page_numbers: List[str] = []\n",
") -> str:\n",
" \"\"\"Perform a vector search over an index, to get answers to specific queries.\n",
" \n",
" Args:\n",
" query (str): The string query to be embedded.\n",
" page_numbers (List[str], optional): Filter by set of pages. Defaults to an empty list.\n",
" If empty, perform a vector search over all pages. Otherwise, filter by the specified pages.\n",
" \n",
" Returns:\n",
" str: The response from the query engine.\n",
" \"\"\"\n",
"\n",
" metadata_dicts = [\n",
" {\"key\": \"page_label\", \"value\": p} for p in page_numbers\n",
" ]\n",
" \n",
" query_engine = vector_index.as_query_engine(\n",
" similarity_top_k=2,\n",
" filters=MetadataFilters.from_dicts(\n",
" metadata_dicts,\n",
" condition=FilterCondition.OR\n",
" ) if page_numbers else None\n",
" )\n",
"\n",
" # ====== Customise prompt template ======\n",
" qa_prompt_tmpl_str = (\n",
" \"Context information is below.\\n\"\n",
" \"---------------------\\n\"\n",
" \"{context_str}\\n\"\n",
" \"---------------------\\n\"\n",
" \"Given the context information above I want you to think step by step to answer the query in a crisp manner, incase case you don't know the answer say 'I don't know!'.\\n\"\n",
" \"Query: {query_str}\\n\"\n",
" \"Answer: \"\n",
" )\n",
" qa_prompt_tmpl = PromptTemplate(qa_prompt_tmpl_str)\n",
"\n",
" query_engine.update_prompts(\n",
" {\"response_synthesizer:text_qa_template\": qa_prompt_tmpl}\n",
" )\n",
"\n",
" response = query_engine.query(query)\n",
" return response\n",
"\n",
"vector_query_tool = FunctionTool.from_defaults(\n",
" name=\"vector_tool\",\n",
" fn=vector_query\n",
")"
]
},
{
"cell_type": "markdown",
"id": "4a522ae0",
"metadata": {},
"source": [
"## Summary query engine tool"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "e8e384c4",
"metadata": {},
"outputs": [],
"source": [
"from typing import List\n",
"from llama_index.core import SummaryIndex\n",
"\n",
"\n",
"def summary_query(\n",
" query: str, \n",
") -> str:\n",
" \"\"\"Only use this when word like summary & summarize exist in the user query & if they exist this function would provide summary of a document based on query.\n",
" \n",
" query (str): the string query for summarization of a document.\n",
" \"\"\"\n",
"\n",
" summary_query_engine = summary_index.as_query_engine(\n",
" response_mode=\"tree_summarize\",\n",
" use_async=True,\n",
" )\n",
"\n",
" # ====== Customise prompt template ======\n",
" summary_template_str = (\n",
" \"Context information is below.\\n\"\n",
" \"---------------------\\n\"\n",
" \"{context_str}\\n\"\n",
" \"---------------------\\n\"\n",
" \"Based on the the context information above and the user query provided below, I want you to think step-by-step and provide a detailed summary of the relevant infromation in a nicely formatted way!'.\\n\"\n",
" \"Query: {query_str}\\n\"\n",
" \"Summary: \"\n",
" )\n",
" summary_template = PromptTemplate(summary_template_str)\n",
"\n",
" summary_query_engine.update_prompts(\n",
" {\"response_synthesizer:summary_template\": summary_template}\n",
" )\n",
"\n",
" response = summary_query_engine.query(query)\n",
" return response\n",
" \n",
"\n",
"summary_query_tool = FunctionTool.from_defaults(\n",
" name=\"summary_tool\",\n",
" fn=summary_query\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "2a408ace-cf25-425b-8248-7028ceabcd42",
"metadata": {
"height": 130,
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1;3;38;5;200mThought: The current language of the user is: English. I need to use a tool to help me answer the question.\n",
"Action: vector_tool\n",
"Action Input: {'query': 'Signature in DsPy', 'page_numbers': []}\n",
"\u001b[0m\u001b[1;3;34mObservation: In DSPy, a signature is a natural-language typed declaration of a function that specifies what a text transformation needs to do. It's a short declarative spec that tells DSPy what a text transformation should accomplish (e.g., \"consume questions and return answers\"). A DSPy signature is essentially a tuple of input fields and output fields, along with an optional instruction. The roles of the input and output fields are typically inferred by DSPy based on their names, but can also be explicitly specified through more advanced programming interfaces.\n",
"\u001b[0m"
]
}
],
"source": [
"response = llm.predict_and_call(\n",
" [vector_query_tool, summary_query_tool], \n",
" \"What is a Signature in DsPy?\",\n",
" verbose=True\n",
")"
]
},
{
"cell_type": "markdown",
"id": "fef4dec0",
"metadata": {},
"source": [
"## Let's add some other tools!"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "21906d47-7266-4479-bbb4-9f392d5c399b",
"metadata": {
"height": 98,
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1;3;38;5;200mThought: The current language of the user is: English. I need to use a tool to help me answer the question.\n",
"Action: summary_tool\n",
"Action Input: {'query': 'summarize this paper'}\n",
"\u001b[0m\u001b[1;3;34mObservation: Here is a detailed summary of the paper:\n",
"\n",
"**Paper Summary**\n",
"\n",
"The paper discusses the capabilities of DSPy, an automatic prompt generator for various machine learning models. The authors demonstrate the effectiveness of DSPy by showcasing its ability to generate high-quality prompts for different tasks and models.\n",
"\n",
"**Key Findings**\n",
"\n",
"* **Automatic Prompt Generation**: DSPy can automatically generate prompts for various tasks, including question-answering, context-to-text (CoT), and multi-hop programs.\n",
"* **Model Agnostic**: DSPy is model-agnostic, meaning it can work with multiple machine learning models without requiring any modifications.\n",
"* **High-Quality Prompts**: The generated prompts are of high quality and effectively capture the nuances of the input context.\n",
"\n",
"**Demonstrations**\n",
"\n",
"The authors provide several demonstrations to illustrate the effectiveness of DSPy, including:\n",
"\n",
"1. **Question Answering**: DSPy generates high-quality prompts for question-answering tasks, achieving accuracy comparable to or surpassing that of human-written prompts.\n",
"2. **Context-to-Text (CoT)**: DSPy is shown to be effective in generating CoT prompts, demonstrating its ability to handle complex context-dependent tasks.\n",
"3. **Multi-Hop Programs**: The authors demonstrate the effectiveness of DSPy in generating prompts for multi-hop programs, showcasing its ability to handle complex, multi-step reasoning tasks.\n",
"\n",
"**Comparison with Existing Methods**\n",
"\n",
"The paper compares the performance of DSPy with existing methods for automatic prompt generation. The results show that DSPy outperforms these methods in terms of accuracy and quality of generated prompts.\n",
"\n",
"**Techniques and Modules**\n",
"\n",
"The paper proposes several new techniques and modules for generating human-like responses in dialogue systems using the DSPy framework, including:\n",
"\n",
"1. **Predict**: A module that generates predictions based on a given input.\n",
"2. **ChainOfThought**: A module that generates a chain of thoughts or reasoning steps to answer a question.\n",
"3. **Teleprompter**: A class that generates human-like responses in dialogue systems using a combination of predict and chain-of-thought modules.\n",
"\n",
"**Examples**\n",
"\n",
"The paper provides several examples of generated prompts, including:\n",
"\n",
"* A prompt for GSM8K that includes a CoT prompt and a generate query prompt from the multihop program.\n",
"* A prompt for HotPotQA that generates search queries from given contexts and questions.\n",
"* A prompt for Llama2-13b-chat that generates answers to questions based on provided contexts.\n",
"\n",
"**Conclusion**\n",
"\n",
"The authors conclude by highlighting the benefits of using DSPy, including its ability to automatically generate high-quality prompts for various machine learning models. The authors suggest that DSPy can be a valuable tool for researchers and developers working on natural language processing tasks.\n",
"\u001b[0m"
]
}
],
"source": [
"response = llm.predict_and_call(\n",
" [vector_query_tool, summary_query_tool], \n",
" \"Can you summarise this paper for me?\", \n",
" verbose=True\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment