{ "cells": [ { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Make sure ollama serve is running(docker or terminal)\n", "from operator import itemgetter\n", "from langchain.prompts import PromptTemplate\n", "from shared import getModel, getEmbeddingsModel, getQdrantClient\n", "\n", "def answer(query):\n", " # Create a qdrant connection\n", " qClient = getQdrantClient()\n", "\n", " # Setup the text embedder\n", " embeddingsModel = getEmbeddingsModel()\n", "\n", " # Setup the model\n", " model = getModel()\n", "\n", " # Retrieval Pipeline\n", " # Retrieve the chunks with the most similar embeddings from Qdrant\n", " def retriever(text, collection):\n", " results = qClient.search(\n", " collection_name=collection,\n", " query_vector = embeddingsModel.embed_query(text),\n", " limit=10\n", " )\n", " return results\n", "\n", " # Query expansion(I only generate one additional prompt for simplicity)\n", " template = \"\"\"\n", " Rewrite the prompt. The new prompt must offer a different perspective.\n", " Do not change the meaning. Output only the rewritten prompt with no introduction.\n", " Prompt: {prompt}\n", " \"\"\"\n", " prompt = PromptTemplate.from_template(template)\n", " chain = {\"prompt\": itemgetter(\"prompt\")} | prompt | model\n", " queryExpansion = chain.invoke({\"prompt\": query})\n", " print(\"Query expansion: \", queryExpansion)\n", "\n", " # Self-querying(The metadata I will be generating determines whether to look through the Qdrant collection containing github code)\n", " template = \"\"\"\n", " You are an AI assistant. You must determine if the prompt requires code as the answer.\n", " Output a 1 if it is or a 0 if it is not and nothing else.\n", " Prompt: {prompt}\n", " \"\"\"\n", " prompt = PromptTemplate.from_template(template)\n", " chain = {\"prompt\": itemgetter(\"prompt\")} | prompt | model\n", " codingQuestion = chain.invoke({\"prompt\": query})\n", " print(\"Coding question?: \", codingQuestion)\n", "\n", " # Filtered vector search for each of the N queries after expansion\n", " relatedCollection = 'Document'\n", " if (codingQuestion == '1'):\n", " relatedCollection = 'Github'\n", " results1 = retriever(query, relatedCollection)\n", " results2 = retriever(queryExpansion, relatedCollection)\n", " print(\"Related collection: \", relatedCollection)\n", " \n", "\n", " # Collecting results\n", " results = results1+results2\n", "\n", " # Reranking(Instead of using a CrossEncoder, I will manually compare embeddings)\n", " ids = [result.id for result in results]\n", " scores = [result.score for result in results]\n", " topIds = []\n", " topIndexes = []\n", " for x in range(3):\n", " maxScore = 0\n", " maxIndex = 0\n", " for i in range(len(ids)):\n", " if ids[i] not in topIds and scores[i] > maxScore:\n", " maxScore = scores[i]\n", " maxIndex = i\n", " topIds.append(ids[maxIndex])\n", " topIndexes.append(maxIndex)\n", " texts = [result.payload['text'] for result in results]\n", " links = [result.payload['link'] for result in results]\n", " topTexts = ''\n", " for index in topIndexes:\n", " print(\"Top texts: \", texts[index])\n", " print(\"Link: \", links[index])\n", " topTexts += texts[index]\n", "\n", " # Building prompt\n", " if(codingQuestion == '1'):\n", " template = \"\"\"\n", " Write code for the following question given the related coding document below.\n", "\n", " Document: {document}\n", " Question: {question}\n", " \"\"\"\n", " prompt = PromptTemplate.from_template(template)\n", " else:\n", " template = \"\"\"\n", " You are an AI agent that has retreived a document from the web.\n", " If the document is useful for answering the question use it.\n", " If the document is not useful, answer normally.\n", " Do not mention the document.\n", "\n", " Document: {document}\n", " Question: {question}\n", " \"\"\"\n", " prompt = PromptTemplate.from_template(template)\n", "\n", " # Obtaining answer\n", " chain = {\"document\": itemgetter(\"document\"), \"question\": itemgetter(\"question\")} | prompt | model\n", " print(\"RAG answer: \", chain.invoke({\"document\": topTexts, \"question\": query}))\n", " print(\"\\n----------------------------------------------\\n\")\n", " baseline = model.invoke(query)\n", " print(\"Baseline answer: \", baseline[:500])\n", " print(\"\\n----------------------------------------------\\n\")\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Query expansion: What percentage of global companies have adopted or are utilizing Nav2?\n", "Coding question?: 0\n", "Related collection: Document\n", "Top texts: types of tasks like object following, complete coverage navigation, and more. Nav2 is a production-grade and high-quality navigation framework trusted by 100+ companies worldwide. It provides perception, planning, control, localization, visualization, and much more to build highly reliable autonomous systems. This will compute an environmental model from sensor and semantic data, dynamically path plan, compute velocities for motors, avoid obstacles, and structure higher-level robot behaviors.\n", "Link: https://docs.nav2.org/\n", "Top texts: not specifically address here. BehaviorTree.CPP upgraded to version 4.5+ Since we migrated from version 3.8 to 4.5, users must upgrade their XML and source code accordingly. You can refer to [this page](https://www.behaviortree.dev/docs/migration) for more details, but the main changes are: XML must be changed. This [python script can help](https://github.com/BehaviorTree/BehaviorTree.CPP/blob/master/convert_v3_to_v4.py). The syntax of SubTrees has changed; the one of SubTreePlus was adopted,\n", "Link: https://docs.nav2.org/migration/Iron.html\n", "Top texts: September 19, 2015 MoveIt! Upcoming Events - RoboBusiness 2015 Come meet MoveIt! developers and users at RoboBusiness 2015 in San Jose... September 17, 2015 Report on First MoveIt! Community Meeting Watch video of the First MoveIt! Community Meeting in case you missed it. Thank you for coming to the MoveIt! Community Meeting and thanks to the present... July 02, 2015 MoveIt! goes underwater! MoveIt! on an underwater Girona500 AUV robot and 4-DOF arm for autonomous underwater manipulation...\n", "Link: https://moveit.ai/blog/\n", "RAG answer: Nav2 is trusted by 100+ companies worldwide.\n", "\n", "----------------------------------------------\n", "\n", "Baseline answer: I don't have any information about a company called \"Nav2.\" It's possible that it's a small or private company, or it may not be well-known. Can you provide more context or clarify which Nav2 you are referring to?\n", "\n", "Alternatively, I can suggest some well-known companies that use Nav (a navigation and mapping platform) for their trust services. For example:\n", "\n", "* Uber uses Nav for its ride-hailing service\n", "* Lyft also uses Nav for its service\n", "* Pizza Hut uses Nav to help customers navigate to location\n", "\n", "----------------------------------------------\n", "\n" ] } ], "source": [ "#queries = [\"How can I develop the navigation stack of an agent with egomotion?\", \"What is ROS?\", \"How many companies is Nav2 trusted by worldwide?\", \"How would I build a ROS 2 Navigation Framework and System?\", \"Write me code to move a robot using Moveit\"]\n", "queries = [\"How many companies is Nav2 trusted by worldwide?\"]\n", "for query in queries:\n", " answer(query)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.12.7" } }, "nbformat": 4, "nbformat_minor": 2 }