Project: YugabyteDB (App Definition and Development / Database)
File: ai-llamaindex-openai.md

title: How to Develop RAG Apps with LlamaIndex, OpenAI and YugabyteDB headerTitle: Build RAG applications with LlamaIndex, OpenAI, and YugabyteDB linkTitle: LlamaIndex and OpenAI description: Learn to build RAG applications using LlamaIndex and OpenAI. image: /images/tutorials/ai/icons/llamaindex-icon.svg headcontent: Use YugabyteDB as the database backend for RAG applications menu: preview_tutorials: identifier: tutorials-ai-llamaindex-openai parent: tutorials-ai weight: 60 type: docs This tutorial demonstrates how use LlamaIndex to build RAG (Retrieval-Augmented Generation) applications. By using the LlamaIndex , the application can query a YugabyteDB database from natural language. It can then infer whether to query a secondary vector index to fetch documents. In this case, the secondary index contains the Wikipedia pages of S&P 500 companies. Python 3 Docker Download the application and provide settings specific to your deployment: Clone the repository. ```sh git clone https://github.com/YugabyteDB-Samples/yugabytedb-llamaindex-sp500-search.git ``` Install the application dependencies. Dependencies can be installed in a virtual environment, or globally on your machine. Option 1 (recommended): Install Dependencies from requirements.txt* in virtual environment. ```sh python3 -m venv yb-llamaindex-env source yb-llamaindex-env/bin/activate pip install -r requirements.txt ``` Option 2: Install Dependencies Globally. ```sh pip install llama-index pip install psycopg2 pip install python-dotenv ``` Create an . This will be used to connect the application to the LLM to generate SQL queries, infer results and generate the proper response. Configure the application environment variables in `{project_directory/.env}`. Start a 3-node YugabyteDB cluster in Docker (or feel free to use another deployment option): ```sh mkdir ~/ybdockerdata docker network create custom-network docker run -d --name yugabytedb-node1 --net custom-network \ -p 15433:15433 -p 7001:7000 -p 9001:9000 -p 5433:5433 \ -v ~/ybdockerdata/node1:/home/yugabyte/yb_data --restart unless-stopped \ yugabytedb/yugabyte:{{< yb-version version="preview" format="build">}} \ bin/yugabyted start \ --basedir=/home/yugabyte/ybdata --background=false docker run -d --name yugabytedb-node2 --net custom-network \ -p 15434:15433 -p 7002:7000 -p 9002:9000 -p 5434:5433 \ -v ~/ybdockerdata/node2:/home/yugabyte/yb_data --restart unless-stopped \ yugabytedb/yugabyte:{{< yb-version version="preview" format="build">}} \ bin/yugabyted start --join=yugabytedb-node1 \ --basedir=/home/yugabyte/ybdata --background=false docker run -d --name yugabytedb-node3 --net custom-network \ -p 15435:15433 -p 7003:7000 -p 9003:9000 -p 5435:5433 \ -v ~/ybdockerdata/node3:/home/yugabyte/yb_data --restart unless-stopped \ yugabytedb/yugabyte:{{< yb-version version="preview" format="build">}} \ bin/yugabyted start --join=yugabytedb-node1 \ --basedir=/home/yugabyte/ybdata --background=false ``` The database connectivity settings are provided in the `{project_dir}/.env` file and do not need to be changed if you started the cluster using the preceding command. Navigate to the YugabyteDB UI to confirm that the database is up and running, at <http://127.0.0.1:15433>. This application requires a database table with financial information for companies in the S&P 500. This schema includes a `companies` table. It also creates a read-only user role to prevent any destructive actions while querying the database directly from LlamaIndex. Copy the schema to the first node's Docker container. ```sh docker cp {project_dir}/sql/schema.sql yugabytedb-node1:/home ``` Copy the seed data file to the Docker container. ```sh docker cp

yugabytedb-node1:/home ``` Execute the SQL files against the database. ```sh docker exec -it yugabytedb-node1 bin/ysqlsh -h yugabytedb-node1 -f /home/schema.sql docker exec -it yugabytedb-node1 bin/ysqlsh -h yugabytedb-node1 -f /home/data.sql ``` This command-line application takes an input in natural language and returns a response from LlamaIndex. Start the server. ```sh python3 index.py ``` ```output What is your question? ``` Provide a relevant question. For instance: ```output What is your question? Provide a detailed company history for the company with the highest marketcap. ``` The AI agent combines insights from YugabyteDB and the Wikipedia vector store to provide an appropriate response. ```output Querying SQL database: The first choice seems more relevant as it mentions translating a natural language query into a SQL query over a table containing companies' stats. This could potentially include the company with the highest marketcap and provide a detailed history. The second choice is more about answering semantic questions, which doesn't necessarily imply detailed company history. SQL query: SELECT * FROM companies WHERE marketcap = (SELECT MAX(marketcap) FROM companies) SQL response: The company with the highest marketcap is Microsoft Corporation. It was founded on April 4, 1975, and is headquartered at One Microsoft Way, Redmond, Washington, United States. Microsoft is a technology company that specializes in software infrastructure. It has a marketcap of $1,043,526,401,920 and employs 221,000 people. The company's contact number is 425-882-8080. Transformed query given SQL response: Can you provide more details about the key products and services offered by Microsoft Corporation? query engine response: Microsoft Corporation offers a wide range of products and services. Some of its key products include operating systems such as Windows, which is used by millions of individuals and businesses worldwide. Microsoft Office Suite is another popular product, which includes applications like Word, Excel, PowerPoint, and Outlook for productivity and communication purposes. The company also offers cloud-based services through its Azure platform, providing infrastructure, analytics, and other solutions for businesses. Additionally, Microsoft develops and sells hardware devices like the Xbox gaming console and Surface tablets. It also provides enterprise software solutions, developer tools, and various other products and services to cater to the needs of different industries and customers. Final response: The company with the highest market cap is Microsoft Corporation. It was founded on April 4, 1975, and is headquartered at One Microsoft Way, Redmond, Washington, United States. Microsoft is a technology company that specializes in software infrastructure. It has a market cap of $1,043,526,401,920 and employs 221,000 people. The company's contact number is 425-882-8080. Microsoft Corporation offers a wide range of products and services. Some of its key products include operating systems such as Windows, which is used by millions of individuals and businesses

Microsoft Office Suite is another popular product, which includes applications like Word, Excel, PowerPoint, and Outlook for productivity and communication purposes. The company also offers cloud-based services through its Azure platform, providing infrastructure, analytics, and other solutions for businesses. Additionally, Microsoft develops and sells hardware devices like the Xbox gaming console and Surface tablets. It also provides enterprise software solutions, developer tools, and various other products and services to cater to the needs of different industries and customers. ``` The Python application relies on both structured and unstructured data to provide an appropriate response. By connecting to the database and providing contextual information, LlamaIndex is able to infer which tables to query and report their columns to the LLM. ```python ... sqlengine = createengine(f"postgresql+psycopg2://{DBUSERNAME}:{DBPASSWORD}@{DBHOST}:{DBPORT}/{DB_NAME}") chunk_size = 1024 llm = OpenAI(temperature=0.1, model="gpt-4", streaming=True) servicecontext = ServiceContext.fromdefaults(chunksize=chunksize, llm=llm) sqldatabase = SQLDatabase(sqlengine, include_tables=["companies"]) from llamaindex.indices.structstore.sql_query import NLSQLTableQueryEngine sqlqueryengine = NLSQLTableQueryEngine( sqldatabase=sqldatabase, tables=["companies"], ) sqltool = QueryEngineTool.fromdefaults( queryengine=sqlquery_engine, description=( "Useful for translating a natural language query into a SQL query over" " a table containing: companies, containing stats about S&P 500 companies." ), ) ``` Additionally, a QueryEngineTool is created for Wikipedia search. This query engine is imported from `wiki_search.py`, which creates a VectorStoreIndex from the documents downloaded from Wikipedia for each S&P 500 company. This index is then stored locally for re-use, preventing the need to index more data and incur more resource costs from the LLM. ```python ... from wikisearch import wikiquery_engine wikitool = QueryEngineTool.fromdefaults( queryengine=wikiquery_engine, description=( f"Useful for answering qualitative questions about different S&P 500 companies." ), ) ... ``` ```python import wikipedia from llamaindex import downloadloader from llamaindex import VectorStoreIndex, StorageContext, loadindexfromstorage WikipediaReader = download_loader("WikipediaReader") PERSISTDIR = "./wikiindex" if not os.path.exists(PERSIST_DIR): wiki_pages = [] for i in range(0, len(symbols)): ticker = yf.Ticker(symbols[i]) if 'longName' in ticker.info: print(ticker.info["longName"]) search_results = wikipedia.search(ticker.info["longName"])[0] wikipages.append(searchresults) loader = WikipediaReader() documents = loader.loaddata(pages=wikipages, auto_suggest=False) print(len(documents)) index = VectorStoreIndex.from_documents(documents) index.storagecontext.persist("wikiindex") wikiqueryengine = index.asqueryengine() print("Created wikiqueryengine for first time") else: storagecontext = StorageContext.fromdefaults(persistdir="wikiindex") index = loadindexfromstorage(storagecontext=storage_context) wikiqueryengine = index.asqueryengine() print("Loaded wikiqueryengine index from storage") ``` Putting it all together, the tools are combined, allowing LlamaIndex and OpenAI to effectively choose how user questions can be answered most efficiently and accurately. ```python query_engine = SQLJoinQueryEngine( sqltool, wikitool, servicecontext=servicecontext ) query_str = input("What is your question? \n\n") while query_str != "": augmentedquerystring = f"Answer this question specifically: {query_str}. Ignore null values." response = queryengine.query(augmentedquery_string) print(response) query_str = input("What is your question? \n\n") ``` LlamaIndex is a powerful tool for building RAG applications over a variety of indexes. This tutorial merely scratches the surface of what's possible, combining structured and unstructured data to build powerful AI applications. For more information about LlamaIndex, see the . If you would like to learn more on building LLM apps with YugabyteDB, check out the tutorial.