mirror of
https://github.com/run-llama/llamacloud-demo.git
synced 2026-07-01 01:37:54 -04:00
Add more examples for LlamaCloud usage (#23)
Adds the following examples for LlamaCloud usage - A corrective RAG agent that uses LlamaCloud query engine as a tool but falls back to web search if the answer isn't found - A workflow that can do both chunk-level and document-level retrieval on LlamaCloud documents - A custom agent that can query both a LlamaCloud query engine and a SQL query engine using workflows. --------- Co-authored-by: Jerry Liu <jerryjliu98@gmail.com>
This commit is contained in:
+165
@@ -0,0 +1,165 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
||||
.pdm.toml
|
||||
.pdm-python
|
||||
.pdm-build/
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
# other
|
||||
.DS_Store
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,462 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Corrective RAG Demo\n",
|
||||
"\n",
|
||||
"This demo shows how you can use LlamaCloud and [Tavily AI](https://tavily.com/) to build a [Corrective RAG](https://arxiv.org/abs/2401.15884) workflow. The workflow uses the indexed documents on Llamacloud as a primary tool, but falls back to web search using Tavily AI if the information presented in the query cannot be found on LlamaCloud.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"A brief understanding of the paper: \n",
|
||||
"Corrective Retrieval Augmented Generation (CRAG) is a method designed to enhance the robustness of language model generation by evaluating and augmenting the relevance of retrieved documents through a an evaluator and large-scale web searches, ensuring more accurate and reliable information is used in generation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"Follow [these instructions](https://docs.cloud.llamaindex.ai/llamacloud/getting_started/quick_start) on how to set up your index. For this example, we will upload a paper about Llama2 onto LlamaCloud. On the configure data source step, download [this PDF paper](https://arxiv.org/pdf/2307.09288) and upload it into your index.\n",
|
||||
"\n",
|
||||
"After deploying your index, follow [these instructions](https://docs.cloud.llamaindex.ai/llamacloud/getting_started/api_key) on getting an API key. Once you are done with this, configure `nest_asyncio` and your enviornment variables."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index llama-index-indices-managed-llama-cloud llama-index-tools-tavily-research"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"<Your OpenAI API Key>\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Designing the Workflow\n",
|
||||
"\n",
|
||||
"Corrective RAG consists of the following steps:\n",
|
||||
"1. Ingestion of data — Loads the data into an index and setting up Tavily AI. The ingestion step will be run by itself, taking in a start event and returning a stop event.\n",
|
||||
"2. Retrieval - Retrives the most relevant nodes based on the query.\n",
|
||||
"3. Relevance evaluation - Uses an LLM to determine whether the retrieved nodes are relevant to the query given the content of the nodes.\n",
|
||||
"4. Relevance extraction - Extracts the nodes which the LLM determined to be relevant.\n",
|
||||
"5. Query transformation and Tavily search - If a node is irrelevant, then uses an LLM to transform the query to tailor towards a web search. Uses Tavily to search the web for a relevant answer based on the query.\n",
|
||||
"6. Response generation - Builds a summary index given the text from the relevant nodes and the Tavily search and uses this index to get a result given the original query.\n",
|
||||
"\n",
|
||||
"The following events are needed:\n",
|
||||
"1. `RetrieveEvent` - Event containing information about the retrieved nodes.\n",
|
||||
"2. `RelevanceEvalEvent` - Event containing a list of the results of the relevance evaluation.\n",
|
||||
"3. `TextExtractEvent` - Event containing the concatenated string of relevant text from relevant nodes.\n",
|
||||
"4. `QueryEvent` - Event containing both the relevant text and search text."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from typing import List\n",
|
||||
"\n",
|
||||
"from llama_index.core.schema import NodeWithScore\n",
|
||||
"from llama_index.core.workflow import (\n",
|
||||
" Event,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"class RetrieveEvent(Event):\n",
|
||||
" \"\"\"Retrieve event (gets retrieved nodes).\"\"\"\n",
|
||||
"\n",
|
||||
" retrieved_nodes: List[NodeWithScore]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class RelevanceEvalEvent(Event):\n",
|
||||
" \"\"\"Relevance evaluation event (gets results of relevance evaluation).\"\"\"\n",
|
||||
"\n",
|
||||
" relevant_results: List[str]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class TextExtractEvent(Event):\n",
|
||||
" \"\"\"Text extract event. Extracts relevant text and concatenates.\"\"\"\n",
|
||||
"\n",
|
||||
" relevant_text: str\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class QueryEvent(Event):\n",
|
||||
" \"\"\"Query event. Queries given relevant text and search text.\"\"\"\n",
|
||||
"\n",
|
||||
" relevant_text: str\n",
|
||||
" search_text: str"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Below is the code for the workflow."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from typing import Optional\n",
|
||||
"\n",
|
||||
"from llama_index.core.workflow import (\n",
|
||||
" StartEvent,\n",
|
||||
" StopEvent,\n",
|
||||
" step,\n",
|
||||
" Workflow,\n",
|
||||
" Context,\n",
|
||||
")\n",
|
||||
"from llama_index.core import SummaryIndex\n",
|
||||
"from llama_index.core.schema import Document\n",
|
||||
"from llama_index.core.prompts import PromptTemplate\n",
|
||||
"from llama_index.core.llms import LLM\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from llama_index.core.base.base_retriever import BaseRetriever\n",
|
||||
"from llama_index.indices.managed.llama_cloud import LlamaCloudIndex\n",
|
||||
"from llama_index.tools.tavily_research import TavilyToolSpec\n",
|
||||
"\n",
|
||||
"DEFAULT_RELEVANCY_PROMPT_TEMPLATE = PromptTemplate(\n",
|
||||
" template=\"\"\"As a grader, your task is to evaluate the relevance of a document retrieved in response to a user's question.\n",
|
||||
"\n",
|
||||
" Retrieved Document:\n",
|
||||
" -------------------\n",
|
||||
" {context_str}\n",
|
||||
"\n",
|
||||
" User Question:\n",
|
||||
" --------------\n",
|
||||
" {query_str}\n",
|
||||
"\n",
|
||||
" Evaluation Criteria:\n",
|
||||
" - Consider whether the document contains keywords or topics related to the user's question.\n",
|
||||
" - The evaluation should not be overly stringent; the primary objective is to identify and filter out clearly irrelevant retrievals.\n",
|
||||
"\n",
|
||||
" Decision:\n",
|
||||
" - Assign a binary score to indicate the document's relevance.\n",
|
||||
" - Use 'yes' if the document is relevant to the question, or 'no' if it is not.\n",
|
||||
"\n",
|
||||
" Please provide your binary score ('yes' or 'no') below to indicate the document's relevance to the user question.\"\"\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"DEFAULT_TRANSFORM_QUERY_TEMPLATE = PromptTemplate(\n",
|
||||
" template=\"\"\"Your task is to refine a query to ensure it is highly effective for retrieving relevant search results. \\n\n",
|
||||
" Analyze the given input to grasp the core semantic intent or meaning. \\n\n",
|
||||
" Original Query:\n",
|
||||
" \\n ------- \\n\n",
|
||||
" {query_str}\n",
|
||||
" \\n ------- \\n\n",
|
||||
" Your goal is to rephrase or enhance this query to improve its search performance. Ensure the revised query is concise and directly aligned with the intended search objective. \\n\n",
|
||||
" Respond with the optimized query only:\"\"\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class CorrectiveRAGWorkflow(Workflow):\n",
|
||||
" @step(pass_context=True)\n",
|
||||
" async def ingest(self, ctx: Context, ev: StartEvent) -> Optional[StopEvent]:\n",
|
||||
" \"\"\"Ingest step (for ingesting docs and initializing index).\"\"\"\n",
|
||||
" tavily_ai_apikey: Optional[str] = ev.get(\"tavily_ai_apikey\")\n",
|
||||
" index: Optional[LlamaCloudIndex] = ev.get(\"index\")\n",
|
||||
"\n",
|
||||
" if any(i is None for i in [tavily_ai_apikey, index]):\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
" llm = OpenAI(model=\"gpt-4\")\n",
|
||||
"\n",
|
||||
" ctx.data[\"llm\"] = llm\n",
|
||||
" ctx.data[\"index\"] = index\n",
|
||||
" ctx.data[\"tavily_tool\"] = TavilyToolSpec(api_key=tavily_ai_apikey)\n",
|
||||
"\n",
|
||||
" return StopEvent()\n",
|
||||
"\n",
|
||||
" @step(pass_context=True)\n",
|
||||
" async def retrieve(self, ctx: Context, ev: StartEvent) -> Optional[RetrieveEvent]:\n",
|
||||
" \"\"\"Retrieve the relevant nodes for the query.\"\"\"\n",
|
||||
" query_str = ev.get(\"query_str\")\n",
|
||||
" retriever_kwargs = ev.get(\"retriever_kwargs\", {})\n",
|
||||
"\n",
|
||||
" if query_str is None:\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
" retriever: BaseRetriever = ctx.data[\"index\"].as_retriever(**retriever_kwargs)\n",
|
||||
" result = retriever.retrieve(query_str)\n",
|
||||
" ctx.data[\"retrieved_nodes\"] = result\n",
|
||||
" ctx.data[\"query_str\"] = query_str\n",
|
||||
" return RetrieveEvent(retrieved_nodes=result)\n",
|
||||
"\n",
|
||||
" @step(pass_context=True)\n",
|
||||
" async def eval_relevance(\n",
|
||||
" self, ctx: Context, ev: RetrieveEvent\n",
|
||||
" ) -> RelevanceEvalEvent:\n",
|
||||
" \"\"\"Evaluate relevancy of retrieved documents with the query.\"\"\"\n",
|
||||
" retrieved_nodes = ev.retrieved_nodes\n",
|
||||
" query_str = ctx.data[\"query_str\"]\n",
|
||||
" llm: LLM = ctx.data[\"llm\"]\n",
|
||||
"\n",
|
||||
" relevancy_results = []\n",
|
||||
" for node in retrieved_nodes:\n",
|
||||
" prompt = DEFAULT_RELEVANCY_PROMPT_TEMPLATE.format(context_str=node.text, query_str=query_str)\n",
|
||||
" relevancy = llm.complete(prompt)\n",
|
||||
" relevancy_results.append(relevancy.text.lower().strip())\n",
|
||||
"\n",
|
||||
" ctx.data[\"relevancy_results\"] = relevancy_results\n",
|
||||
" return RelevanceEvalEvent(relevant_results=relevancy_results)\n",
|
||||
"\n",
|
||||
" @step(pass_context=True)\n",
|
||||
" async def extract_relevant_texts(\n",
|
||||
" self, ctx: Context, ev: RelevanceEvalEvent\n",
|
||||
" ) -> TextExtractEvent:\n",
|
||||
" \"\"\"Extract relevant texts from retrieved documents.\"\"\"\n",
|
||||
" retrieved_nodes = ctx.data[\"retrieved_nodes\"]\n",
|
||||
" relevancy_results = ev.relevant_results\n",
|
||||
"\n",
|
||||
" relevant_texts = [\n",
|
||||
" retrieved_nodes[i].text\n",
|
||||
" for i, result in enumerate(relevancy_results)\n",
|
||||
" if result == \"yes\"\n",
|
||||
" ]\n",
|
||||
"\n",
|
||||
" result = \"\\n\".join(relevant_texts)\n",
|
||||
" return TextExtractEvent(relevant_text=result)\n",
|
||||
"\n",
|
||||
" @step(pass_context=True)\n",
|
||||
" async def transform_query_pipeline(\n",
|
||||
" self, ctx: Context, ev: TextExtractEvent\n",
|
||||
" ) -> QueryEvent:\n",
|
||||
" \"\"\"Search the transformed query with Tavily API.\"\"\"\n",
|
||||
" relevant_text = ev.relevant_text\n",
|
||||
" relevancy_results = ctx.data[\"relevancy_results\"]\n",
|
||||
" query_str = ctx.data[\"query_str\"]\n",
|
||||
" llm: LLM = ctx.data[\"llm\"]\n",
|
||||
"\n",
|
||||
" # If any document is found irrelevant, transform the query string for better search results.\n",
|
||||
" if \"no\" in relevancy_results:\n",
|
||||
" prompt = DEFAULT_TRANSFORM_QUERY_TEMPLATE.format(query_str=query_str)\n",
|
||||
" result = llm.complete(prompt)\n",
|
||||
" transformed_query_str = result.text\n",
|
||||
"\n",
|
||||
" # Conduct a search with the transformed query string and collect the results.\n",
|
||||
" search_results = ctx.data[\"tavily_tool\"].search(\n",
|
||||
" transformed_query_str, max_results=5\n",
|
||||
" )\n",
|
||||
" search_text = \"\\n\".join([result.text for result in search_results])\n",
|
||||
" else:\n",
|
||||
" search_text = \"\"\n",
|
||||
"\n",
|
||||
" return QueryEvent(relevant_text=relevant_text, search_text=search_text)\n",
|
||||
"\n",
|
||||
" @step(pass_context=True)\n",
|
||||
" async def query_result(self, ctx: Context, ev: QueryEvent) -> StopEvent:\n",
|
||||
" \"\"\"Get result with relevant text.\"\"\"\n",
|
||||
" relevant_text = ev.relevant_text\n",
|
||||
" search_text = ev.search_text\n",
|
||||
" query_str = ctx.data[\"query_str\"]\n",
|
||||
"\n",
|
||||
" documents = [Document(text=relevant_text + \"\\n\" + search_text)]\n",
|
||||
" index = SummaryIndex.from_documents(documents)\n",
|
||||
" query_engine = index.as_query_engine()\n",
|
||||
" result = query_engine.query(query_str)\n",
|
||||
" return StopEvent(result=result)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Create LlamaCloudIndex\n",
|
||||
"\n",
|
||||
"Create a `LlamaCloudIndex` which retrieves information from the index you have on LlamaCloud."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.indices.managed.llama_cloud import LlamaCloudIndex\n",
|
||||
"\n",
|
||||
"index = LlamaCloudIndex(\n",
|
||||
" name=\"<Your index name>\",\n",
|
||||
" project_name=\"<Your project name>\",\n",
|
||||
" api_key=\"llx-...\",\n",
|
||||
" organization_id=\"<Your organization ID>\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"See [here](https://docs.cloud.llamaindex.ai/organizations) for a tutorial on how to use organizations."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Set up the workflow ingestion:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Running step ingest\n",
|
||||
"Step ingest produced event StopEvent\n",
|
||||
"Running step retrieve\n",
|
||||
"Step retrieve produced no event\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"workflow = CorrectiveRAGWorkflow(verbose=True, timeout=60)\n",
|
||||
"await workflow.run(index=index, tavily_ai_apikey=\"<Your Tavily AI API Key>\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Example queries"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Running step ingest\n",
|
||||
"Step ingest produced no event\n",
|
||||
"Running step retrieve\n",
|
||||
"Step retrieve produced event RetrieveEvent\n",
|
||||
"Running step eval_relevance\n",
|
||||
"Step eval_relevance produced event RelevanceEvalEvent\n",
|
||||
"Running step extract_relevant_texts\n",
|
||||
"Step extract_relevant_texts produced event TextExtractEvent\n",
|
||||
"Running step transform_query_pipeline\n",
|
||||
"Step transform_query_pipeline produced event QueryEvent\n",
|
||||
"Running step query_result\n",
|
||||
"Step query_result produced event StopEvent\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"Llama 2 was pretrained on Meta's Research Super Cluster and production clusters using NVIDIA A100 GPUs. The pretraining process involved utilizing custom training libraries and third-party cloud compute for fine-tuning, annotation, and evaluation. The pretraining data consisted of 2 trillion tokens from publicly available sources, with a cutoff date of September 2022. The carbon footprint of the pretraining process amounted to 539 tCO2eq, which was fully offset by Meta's sustainability program."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from IPython.display import display, Markdown\n",
|
||||
"\n",
|
||||
"result = await workflow.run(query_str=\"How was Llama2 pretrained?\") # this was in the given paper\n",
|
||||
"display(Markdown(str(result)))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Running step ingest\n",
|
||||
"Step ingest produced no event\n",
|
||||
"Running step retrieve\n",
|
||||
"Step retrieve produced event RetrieveEvent\n",
|
||||
"Running step eval_relevance\n",
|
||||
"Step eval_relevance produced event RelevanceEvalEvent\n",
|
||||
"Running step extract_relevant_texts\n",
|
||||
"Step extract_relevant_texts produced event TextExtractEvent\n",
|
||||
"Running step transform_query_pipeline\n",
|
||||
"Step transform_query_pipeline produced event QueryEvent\n",
|
||||
"Running step query_result\n",
|
||||
"Step query_result produced event StopEvent\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"The airline flight UA 1 flies from San Francisco, United States to Singapore."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result = await workflow.run(query_str=\"Where does the airline flight UA 1 fly?\") # this info is not in the paper\n",
|
||||
"display(Markdown(str(result)))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"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.10.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -0,0 +1,715 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# SQL and LlamaCloud Router Query Engine\n",
|
||||
"\n",
|
||||
"This notebook shows you how to create a custom agent that can query either your LlamaCloud index or a separate SQL query engine as a tool. In this example, we'll use PDFs of Wikipedia pages of US cities and a SQL database of their populations and states as documents.\n",
|
||||
"\n",
|
||||
"**NOTE**: Any Text-to-SQL application should be aware that executing arbitrary SQL queries can be a security risk. It is recommended to take precautions as needed, such as using restricted roles, read-only databases, sandboxing, etc."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"Set up your OpenAI API key and `nest_asyncio`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"<Your OpenAI API Key>\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load Documents into LlamaCloud\n",
|
||||
"\n",
|
||||
"Download the following Wikipedia pages into PDFs by either pressing Ctrl-P/Cmd-P or right-clicking and selecting \"Print\" and then \"Save as PDF\" as the destination.\n",
|
||||
"- [New York City](https://en.wikipedia.org/wiki/New_York_City)\n",
|
||||
"- [Los Angeles](https://en.wikipedia.org/wiki/Los_Angeles)\n",
|
||||
"- [Chicago](https://en.wikipedia.org/wiki/Chicago)\n",
|
||||
"- [Houston](https://en.wikipedia.org/wiki/Houston)\n",
|
||||
"- [Miami](https://en.wikipedia.org/wiki/Miami)\n",
|
||||
"- [Seattle](https://en.wikipedia.org/wiki/Seattle)\n",
|
||||
"\n",
|
||||
"After that, create a new index in LlamaCloud and upload your PDFs.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## SQL Database\n",
|
||||
"\n",
|
||||
"The SQL database in this example will be created in memory and will contain three columns: the city name, the city's population, and the state the city is located in. The table creation and the information for each city is shown in the snippets below."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import SQLDatabase, Settings\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from sqlalchemy import (\n",
|
||||
" create_engine,\n",
|
||||
" MetaData,\n",
|
||||
" Table,\n",
|
||||
" Column,\n",
|
||||
" String,\n",
|
||||
" Integer,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"Settings.llm = OpenAI(\"gpt-3.5-turbo\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"engine = create_engine(\"sqlite:///:memory:\", future=True)\n",
|
||||
"metadata_obj = MetaData()\n",
|
||||
"\n",
|
||||
"# create city SQL table\n",
|
||||
"table_name = \"city_stats\"\n",
|
||||
"city_stats_table = Table(\n",
|
||||
" table_name,\n",
|
||||
" metadata_obj,\n",
|
||||
" Column(\"city_name\", String(16), primary_key=True),\n",
|
||||
" Column(\"population\", Integer),\n",
|
||||
" Column(\"state\", String(16), nullable=False),\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"metadata_obj.create_all(engine)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[('New York City', 8336000, 'New York'), ('Los Angeles', 3822000, 'California'), ('Chicago', 2665000, 'Illinois'), ('Houston', 2303000, 'Texas'), ('Miami', 449514, 'Florida'), ('Seattle', 749256, 'Washington')]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from sqlalchemy import insert\n",
|
||||
"\n",
|
||||
"rows = [\n",
|
||||
" {\"city_name\": \"New York City\", \"population\": 8336000, \"state\": \"New York\"},\n",
|
||||
" {\"city_name\": \"Los Angeles\", \"population\": 3822000, \"state\": \"California\"},\n",
|
||||
" {\"city_name\": \"Chicago\", \"population\": 2665000, \"state\": \"Illinois\"},\n",
|
||||
" {\"city_name\": \"Houston\", \"population\": 2303000, \"state\": \"Texas\"},\n",
|
||||
" {\"city_name\": \"Miami\", \"population\": 449514, \"state\": \"Florida\"},\n",
|
||||
" {\"city_name\": \"Seattle\", \"population\": 749256, \"state\": \"Washington\"},\n",
|
||||
"]\n",
|
||||
"for row in rows:\n",
|
||||
" stmt = insert(city_stats_table).values(**row)\n",
|
||||
" with engine.begin() as connection:\n",
|
||||
" cursor = connection.execute(stmt)\n",
|
||||
"\n",
|
||||
"with engine.connect() as connection:\n",
|
||||
" cursor = connection.exec_driver_sql(\"SELECT * FROM city_stats\")\n",
|
||||
" print(cursor.fetchall())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Create a query engine based on SQL database."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.query_engine import NLSQLTableQueryEngine\n",
|
||||
"\n",
|
||||
"sql_database = SQLDatabase(engine, include_tables=[\"city_stats\"])\n",
|
||||
"sql_query_engine = NLSQLTableQueryEngine(\n",
|
||||
" sql_database=sql_database,\n",
|
||||
" tables=[\"city_stats\"]\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## LlamaCloud Index\n",
|
||||
"\n",
|
||||
"Create an index and a query engine around the index you've created."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.indices.managed.llama_cloud import LlamaCloudIndex\n",
|
||||
"\n",
|
||||
"index = LlamaCloudIndex(\n",
|
||||
" name=\"<Your Index Name>\", \n",
|
||||
" project_name=\"<Your Project Name>\",\n",
|
||||
" organization_id=\"<Your Org ID>\",\n",
|
||||
" api_key=\"<Your API Key>\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"llama_cloud_query_engine = index.as_query_engine()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Create a query engine tool around these query engines."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.tools import QueryEngineTool\n",
|
||||
"\n",
|
||||
"sql_tool = QueryEngineTool.from_defaults(\n",
|
||||
" query_engine=sql_query_engine,\n",
|
||||
" description=(\n",
|
||||
" \"Useful for translating a natural language query into a SQL query over\"\n",
|
||||
" \" a table containing: city_stats, containing the population/state of\"\n",
|
||||
" \" each city located in the USA.\"\n",
|
||||
" ),\n",
|
||||
" name=\"sql_tool\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"cities = [\"New York City\", \"Los Angeles\", \"Chicago\", \"Houston\", \"Miami\", \"Seattle\"]\n",
|
||||
"llama_cloud_tool = QueryEngineTool.from_defaults(\n",
|
||||
" query_engine=llama_cloud_query_engine,\n",
|
||||
" description=(\n",
|
||||
" f\"Useful for answering semantic questions about certain cities in the US.\"\n",
|
||||
" ),\n",
|
||||
" name=\"llama_cloud_tool\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Creating an Agent Around the Query Engines\n",
|
||||
"\n",
|
||||
"We'll create a workflow that acts as an agent around the two query engines. In this workflow, we need four events:\n",
|
||||
"1. `GatherToolsEvent`: Gets all tools that need to be called (which is determined by the LLM).\n",
|
||||
"2. `ToolCallEvent`: An individual tool call. Multiple of these events will be triggered at the same time.\n",
|
||||
"3. `ToolCallEventResult`: Gets result from a tool call.\n",
|
||||
"4. `GatherEvent`: Returned from dispatcher that triggers the `ToolCallEvent`.\n",
|
||||
"\n",
|
||||
"This workflow consists of the following steps:\n",
|
||||
"1. `chat()`: Appends the message to the chat history. This chat history is fed into the LLM, along with the given tools, and the LLM determines which tools to call. This returns a `GatherToolsEvent`.\n",
|
||||
"2. `dispatch_calls()`: Triggers a `ToolCallEvent` for each tool call given in the `GatherToolsEvent` using `send_event()`. Returns a `GatherEvent` with the number of tool calls.\n",
|
||||
"3. `call_tool()`: Calls an individual tool. This step will run multiple times if there is more than one tool call. This step calls the tool and appends the result as a chat message to the chat history. It returns a `ToolCallEventResult` with the result of the tool call.\n",
|
||||
"4. `gather()`: Gathers the results from all tool calls using `collect_events()`. Waits for all tool calls to finish, then feeds chat history (following all tool calls) into the LLM. Returns the response from the LLM."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from typing import Dict, List\n",
|
||||
"\n",
|
||||
"from llama_index.core.tools import BaseTool\n",
|
||||
"from llama_index.core.llms import ChatMessage\n",
|
||||
"from llama_index.core.llms.llm import ToolSelection\n",
|
||||
"from llama_index.core.workflow import Context, Workflow\n",
|
||||
"from llama_index.core.base.response.schema import Response\n",
|
||||
"from llama_index.core.tools import FunctionTool\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class InputEvent(Event):\n",
|
||||
" \"\"\"Input event.\"\"\"\n",
|
||||
"\n",
|
||||
"class GatherToolsEvent(Event):\n",
|
||||
" \"\"\"Gather Tools Event\"\"\"\n",
|
||||
"\n",
|
||||
" tool_calls: Any\n",
|
||||
"\n",
|
||||
"class ToolCallEvent(Event):\n",
|
||||
" \"\"\"Tool Call event\"\"\"\n",
|
||||
"\n",
|
||||
" tool_call: ToolSelection\n",
|
||||
"\n",
|
||||
"class ToolCallEventResult(Event):\n",
|
||||
" \"\"\"Tool call event result.\"\"\"\n",
|
||||
"\n",
|
||||
" msg: ChatMessage\n",
|
||||
"\n",
|
||||
"class RouterOutputAgentWorkflow(Workflow):\n",
|
||||
" \"\"\"Custom router output agent workflow.\"\"\"\n",
|
||||
"\n",
|
||||
" def __init__(self,\n",
|
||||
" tools: List[BaseTool],\n",
|
||||
" timeout: Optional[float] = 10.0,\n",
|
||||
" disable_validation: bool = False,\n",
|
||||
" verbose: bool = False,\n",
|
||||
" llm: Optional[LLM] = None,\n",
|
||||
" chat_history: Optional[List[ChatMessage]] = None,\n",
|
||||
" ):\n",
|
||||
" \"\"\"Constructor.\"\"\"\n",
|
||||
"\n",
|
||||
" super().__init__(timeout=timeout, disable_validation=disable_validation, verbose=verbose)\n",
|
||||
"\n",
|
||||
" self.tools: List[BaseTool] = tools\n",
|
||||
" self.tools_dict: Optional[Dict[str, BaseTool]] = {tool.metadata.name: tool for tool in self.tools}\n",
|
||||
" self.llm: LLM = llm or OpenAI(temperature=0, model=\"gpt-3.5-turbo\")\n",
|
||||
" self.chat_history: List[ChatMessage] = chat_history or []\n",
|
||||
" \n",
|
||||
"\n",
|
||||
" def reset(self) -> None:\n",
|
||||
" \"\"\"Resets Chat History\"\"\"\n",
|
||||
"\n",
|
||||
" self.chat_history = []\n",
|
||||
"\n",
|
||||
" @step()\n",
|
||||
" async def prepare_chat(self, ev: StartEvent) -> InputEvent:\n",
|
||||
" message = ev.get(\"message\")\n",
|
||||
" if message is None:\n",
|
||||
" raise ValueError(\"'message' field is required.\")\n",
|
||||
" \n",
|
||||
" # add msg to chat history\n",
|
||||
" chat_history = self.chat_history\n",
|
||||
" chat_history.append(ChatMessage(role=\"user\", content=message))\n",
|
||||
" return InputEvent()\n",
|
||||
"\n",
|
||||
" @step()\n",
|
||||
" async def chat(self, ev: InputEvent) -> GatherToolsEvent | StopEvent:\n",
|
||||
" \"\"\"Appends msg to chat history, then gets tool calls.\"\"\"\n",
|
||||
"\n",
|
||||
" # Put msg into LLM with tools included\n",
|
||||
" chat_res = await self.llm.achat_with_tools(\n",
|
||||
" self.tools,\n",
|
||||
" chat_history=self.chat_history,\n",
|
||||
" verbose=self._verbose,\n",
|
||||
" allow_parallel_tool_calls=True\n",
|
||||
" )\n",
|
||||
" tool_calls = self.llm.get_tool_calls_from_response(chat_res, error_on_no_tool_call=False)\n",
|
||||
" \n",
|
||||
" ai_message = chat_res.message\n",
|
||||
" self.chat_history.append(ai_message)\n",
|
||||
" if self._verbose:\n",
|
||||
" print(f\"Chat message: {ai_message.content}\")\n",
|
||||
"\n",
|
||||
" # no tool calls, return chat message.\n",
|
||||
" if not tool_calls:\n",
|
||||
" return StopEvent(result=ai_message.content)\n",
|
||||
"\n",
|
||||
" return GatherToolsEvent(tool_calls=tool_calls)\n",
|
||||
"\n",
|
||||
" @step(pass_context=True)\n",
|
||||
" async def dispatch_calls(self, ctx: Context, ev: GatherToolsEvent) -> ToolCallEvent:\n",
|
||||
" \"\"\"Dispatches calls.\"\"\"\n",
|
||||
"\n",
|
||||
" tool_calls = ev.tool_calls\n",
|
||||
" ctx.data[\"num_tool_calls\"] = len(tool_calls)\n",
|
||||
"\n",
|
||||
" # trigger tool call events\n",
|
||||
" for tool_call in tool_calls:\n",
|
||||
" self.send_event(ToolCallEvent(tool_call=tool_call))\n",
|
||||
" \n",
|
||||
" return None\n",
|
||||
" \n",
|
||||
" @step()\n",
|
||||
" async def call_tool(self, ev: ToolCallEvent) -> ToolCallEventResult:\n",
|
||||
" \"\"\"Calls tool.\"\"\"\n",
|
||||
"\n",
|
||||
" tool_call = ev.tool_call\n",
|
||||
"\n",
|
||||
" # get tool ID and function call\n",
|
||||
" id_ = tool_call.tool_id\n",
|
||||
"\n",
|
||||
" if self._verbose:\n",
|
||||
" print(f\"Calling function {tool_call.tool_name} with msg {tool_call.tool_kwargs}\")\n",
|
||||
"\n",
|
||||
" # call function and put result into a chat message\n",
|
||||
" tool = self.tools_dict[tool_call.tool_name]\n",
|
||||
" output = await tool.acall(**tool_call.tool_kwargs)\n",
|
||||
" msg = ChatMessage(\n",
|
||||
" name=tool_call.tool_name,\n",
|
||||
" content=str(output),\n",
|
||||
" role=\"tool\",\n",
|
||||
" additional_kwargs={\n",
|
||||
" \"tool_call_id\": id_,\n",
|
||||
" \"name\": tool_call.tool_name\n",
|
||||
" }\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" return ToolCallEventResult(msg=msg)\n",
|
||||
" \n",
|
||||
" @step(pass_context=True)\n",
|
||||
" async def gather(self, ctx: Context, ev: ToolCallEventResult) -> StopEvent | None:\n",
|
||||
" \"\"\"Gathers tool calls.\"\"\"\n",
|
||||
" # wait for all tool call events to finish.\n",
|
||||
" tool_events = ctx.collect_events(ev, [ToolCallEventResult] * ctx.data[\"num_tool_calls\"])\n",
|
||||
" if not tool_events:\n",
|
||||
" return None\n",
|
||||
" \n",
|
||||
" for tool_event in tool_events:\n",
|
||||
" # append tool call chat messages to history\n",
|
||||
" self.chat_history.append(tool_event.msg)\n",
|
||||
" \n",
|
||||
" # # after all tool calls finish, pass input event back, restart agent loop\n",
|
||||
" return InputEvent()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Create the workflow instance."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"wf = RouterOutputAgentWorkflow(tools=[sql_tool, llama_cloud_tool], verbose=True, timeout=120)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Example Queries"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Running step prepare_chat\n",
|
||||
"Step prepare_chat produced event InputEvent\n",
|
||||
"Running step chat\n",
|
||||
"Chat message: None\n",
|
||||
"Step chat produced event GatherToolsEvent\n",
|
||||
"Running step dispatch_calls\n",
|
||||
"Step dispatch_calls produced no event\n",
|
||||
"Running step call_tool\n",
|
||||
"Calling function sql_tool with msg {'input': 'SELECT city FROM city_stats ORDER BY population DESC LIMIT 1'}\n",
|
||||
"Step call_tool produced event ToolCallEventResult\n",
|
||||
"Running step gather\n",
|
||||
"Step gather produced event InputEvent\n",
|
||||
"Running step chat\n",
|
||||
"Chat message: New York City has the highest population among all cities in the USA.\n",
|
||||
"Step chat produced event StopEvent\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"New York City has the highest population among all cities in the USA."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from IPython.display import display, Markdown\n",
|
||||
"\n",
|
||||
"result = await wf.run(message=\"Which city has the highest population?\")\n",
|
||||
"display(Markdown(result))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Running step prepare_chat\n",
|
||||
"Step prepare_chat produced event InputEvent\n",
|
||||
"Running step chat\n",
|
||||
"Chat message: None\n",
|
||||
"Step chat produced event GatherToolsEvent\n",
|
||||
"Running step dispatch_calls\n",
|
||||
"Step dispatch_calls produced no event\n",
|
||||
"Running step call_tool\n",
|
||||
"Calling function llama_cloud_tool with msg {'input': 'What state is Houston located in?'}\n",
|
||||
"Step call_tool produced event ToolCallEventResult\n",
|
||||
"Running step gather\n",
|
||||
"Step gather produced event InputEvent\n",
|
||||
"Running step chat\n",
|
||||
"Chat message: Houston is located in the state of Texas.\n",
|
||||
"Step chat produced event StopEvent\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"Houston is located in the state of Texas."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result = await wf.run(message=\"What state is Houston located in?\")\n",
|
||||
"display(Markdown(result))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Running step prepare_chat\n",
|
||||
"Step prepare_chat produced event InputEvent\n",
|
||||
"Running step chat\n",
|
||||
"Chat message: None\n",
|
||||
"Step chat produced event GatherToolsEvent\n",
|
||||
"Running step dispatch_calls\n",
|
||||
"Step dispatch_calls produced no event\n",
|
||||
"Running step call_tool\n",
|
||||
"Calling function llama_cloud_tool with msg {'input': 'Where is the Space Needle located?'}\n",
|
||||
"Step call_tool produced event ToolCallEventResult\n",
|
||||
"Running step gather\n",
|
||||
"Step gather produced event InputEvent\n",
|
||||
"Running step chat\n",
|
||||
"Chat message: The Space Needle is located in Seattle.\n",
|
||||
"Step chat produced event StopEvent\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"The Space Needle is located in Seattle."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result = await wf.run(message=\"Where is the Space Needle located?\")\n",
|
||||
"display(Markdown(result))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Running step prepare_chat\n",
|
||||
"Step prepare_chat produced event InputEvent\n",
|
||||
"Running step chat\n",
|
||||
"Chat message: None\n",
|
||||
"Step chat produced event GatherToolsEvent\n",
|
||||
"Running step dispatch_calls\n",
|
||||
"Step dispatch_calls produced no event\n",
|
||||
"Running step call_tool\n",
|
||||
"Calling function llama_cloud_tool with msg {'input': 'List all of the places to visit in Miami'}\n",
|
||||
"Step call_tool produced event ToolCallEventResult\n",
|
||||
"Running step gather\n",
|
||||
"Step gather produced event InputEvent\n",
|
||||
"Running step chat\n",
|
||||
"Chat message: Here are some places to visit in Miami:\n",
|
||||
"1. South Beach\n",
|
||||
"2. Art Deco Historic District\n",
|
||||
"3. Wynwood Walls\n",
|
||||
"4. Vizcaya Museum and Gardens\n",
|
||||
"5. Little Havana\n",
|
||||
"6. Perez Art Museum Miami\n",
|
||||
"7. Frost Science Museum\n",
|
||||
"8. Miami Seaquarium\n",
|
||||
"Step chat produced event StopEvent\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"Here are some places to visit in Miami:\n",
|
||||
"1. South Beach\n",
|
||||
"2. Art Deco Historic District\n",
|
||||
"3. Wynwood Walls\n",
|
||||
"4. Vizcaya Museum and Gardens\n",
|
||||
"5. Little Havana\n",
|
||||
"6. Perez Art Museum Miami\n",
|
||||
"7. Frost Science Museum\n",
|
||||
"8. Miami Seaquarium"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result = await wf.run(message=\"List all of the places to visit in Miami.\")\n",
|
||||
"display(Markdown(result))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Running step chat\n",
|
||||
"Chat message: None\n",
|
||||
"Step chat produced event GatherToolsEvent\n",
|
||||
"Running step dispatch_calls\n",
|
||||
"Step dispatch_calls produced event GatherEvent\n",
|
||||
"Running step gather\n",
|
||||
"Step gather produced no event\n",
|
||||
"Running step call_tool\n",
|
||||
"Calling function llama_cloud_tool with msg {\"input\":\"How do people in Chicago get around?\"}\n",
|
||||
"Step call_tool produced event ToolCallEventResult\n",
|
||||
"Running step gather\n",
|
||||
"Step gather produced event StopEvent\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"People in Chicago get around using various transportation options such as Metra commuter rail, Pace bus and paratransit services, Chicago Transit Authority (CTA) buses and rapid transit system (known as the \"L\"), Greyhound Lines inter-city buses, Megabus services, Divvy bike-sharing system, and electric scooter sharing programs. Additionally, Chicago is a major hub for passenger rail services provided by Amtrak, with services connecting to various cities across the United States."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result = await wf.run(message=\"How do people in Chicago get around?\")\n",
|
||||
"display(Markdown(result))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Running step chat\n",
|
||||
"Chat message: None\n",
|
||||
"Step chat produced event GatherToolsEvent\n",
|
||||
"Running step dispatch_calls\n",
|
||||
"Step dispatch_calls produced event GatherEvent\n",
|
||||
"Running step gather\n",
|
||||
"Step gather produced no event\n",
|
||||
"Running step call_tool\n",
|
||||
"Calling function llama_cloud_tool with msg {\"input\":\"What is the historical name of Los Angeles?\"}\n",
|
||||
"Step call_tool produced event ToolCallEventResult\n",
|
||||
"Running step gather\n",
|
||||
"Step gather produced event StopEvent\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"The historical name of Los Angeles is \"El Pueblo de Nuestra Señora la Reina de los Ángeles,\" which translates to 'The Town of Our Lady the Queen of the Angels'."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result = await wf.run(message=\"What is the historical name of Los Angeles?\")\n",
|
||||
"display(Markdown(result))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llamacloud-demo",
|
||||
"language": "python",
|
||||
"name": "llamacloud-demo"
|
||||
},
|
||||
"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.10.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
Reference in New Issue
Block a user