From b64db83e00bd2e5c6a93e391e5d5e655bc9d5ca0 Mon Sep 17 00:00:00 2001 From: alejandro Date: Wed, 27 Nov 2024 14:17:28 -0500 Subject: [PATCH 1/3] feat: adding built-in summarization tool for synthesizing cortex search outputs when needed --- agent_gateway/gateway/gateway.py | 17 ++++++++- agent_gateway/gateway/output_parser.py | 53 +++++++++++++++++++++++++- agent_gateway/gateway/planner.py | 10 +++-- 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/agent_gateway/gateway/gateway.py b/agent_gateway/gateway/gateway.py index d781beb..5e40664 100644 --- a/agent_gateway/gateway/gateway.py +++ b/agent_gateway/gateway/gateway.py @@ -114,6 +114,16 @@ def _parse_snowflake_response(self, data_str): ) +class SummarizationAgent(Tool): + def __init__(self, session, agent_llm): + tool_name = "summarize" + tool_description = "Concisely summarizes cortex search output" + summarizer = CortexCompleteAgent(session=session, llm=agent_llm) + super().__init__( + name=tool_name, func=summarizer.arun, description=tool_description + ) + + class Agent(Chain, extra="allow"): """Cortex Gateway Multi Agent Class""" @@ -161,12 +171,17 @@ def __init__( if not planner_example_prompt_replan: planner_example_prompt_replan = planner_example_prompt + summarizer = SummarizationAgent( + session=snowflake_connection, agent_llm=agent_llm + ) + tools_with_summarizer = tools + [summarizer] + self.planner = Planner( session=snowflake_connection, llm=planner_llm, example_prompt=planner_example_prompt, example_prompt_replan=planner_example_prompt_replan, - tools=tools, + tools=tools_with_summarizer, stop=planner_stop, ) diff --git a/agent_gateway/gateway/output_parser.py b/agent_gateway/gateway/output_parser.py index ec2170f..9fe6395 100644 --- a/agent_gateway/gateway/output_parser.py +++ b/agent_gateway/gateway/output_parser.py @@ -42,12 +42,12 @@ def parse(self, text: str) -> list[str]: # 1. search("Ronaldo number of kids") -> 1, "search", '"Ronaldo number of kids"' # pattern = r"(\d+)\. (\w+)\(([^)]+)\)" pattern = rf"(?:{THOUGHT_PATTERN}\n)?{ACTION_PATTERN}" - # matches = re.findall(pattern, text) matches = re.findall(pattern, text, re.DOTALL) + final_matches = _update_task_list_with_summarization(matches) graph_dict = {} - for match in matches: + for match in final_matches: # idx = 1, function = "search", args = "Ronaldo number of kids" # thought will be the preceding thought, if any, otherwise an empty string thought, idx, tool_name, args, _ = match @@ -69,6 +69,55 @@ def parse(self, text: str) -> list[str]: ### Helper functions +def _initialize_task_list(matches): + new_matches = [] + current_index = 1 + index_mapping = {} + + for i, task in enumerate(matches): + index_mapping[task[1]] = str(current_index) + updated_task = (task[0], str(current_index), task[2], task[3]) + new_matches.append(updated_task) + + if "cortexsearch" in task[2] and i != len(matches) - 2: + new_step = _create_summarization_step(task[3], current_index) + new_matches.append(new_step) + current_index += 1 + index_mapping[task[1]] = str(current_index) + + current_index += 1 + + return new_matches, index_mapping + + +def _create_summarization_step(context, index): + summarization_prompt = f"Think step by step in order to give me {context} using the following context: ${index}" + return ( + "I need to concisely summarize the cortex search output", + str(index + 1), + "summarize", + summarization_prompt, + ) + + +def _update_task_references(task, index_mapping): + updated_string = task[3] + updated_string = re.sub( + r"\$(\d+)", + lambda m: f"${index_mapping.get(m.group(1), m.group(1))}", + updated_string, + ) + return (task[0], task[1], task[2], updated_string) + + +def _update_task_list_with_summarization(matches): + new_matches, index_mapping = _initialize_task_list(matches) + updated_final_matches = [ + _update_task_references(task, index_mapping) for task in new_matches + ] + return updated_final_matches + + def _parse_llm_compiler_action_args(args: str) -> Union[Tuple[Any, ...], Tuple[str]]: """Parse arguments from a string.""" args = args.strip() diff --git a/agent_gateway/gateway/planner.py b/agent_gateway/gateway/planner.py index 128973b..2dc006e 100644 --- a/agent_gateway/gateway/planner.py +++ b/agent_gateway/gateway/planner.py @@ -216,17 +216,21 @@ def __init__( ): self.llm = llm self.session = session + self.tools = tools + + tools_without_summarizer = [i for i in self.tools if (i.name != "summarize")] + self.system_prompt = generate_gateway_prompt( - tools=tools, + tools=tools_without_summarizer, example_prompt=example_prompt, is_replan=False, ) self.system_prompt_replan = generate_gateway_prompt( - tools=tools, + tools=tools_without_summarizer, example_prompt=example_prompt_replan, is_replan=True, ) - self.tools = tools + # self.tools = tools self.output_parser = GatewayPlanParser(tools=tools) self.stop = stop From 8afe08a8f94870958e6273f2a8efd33e88dd7dd8 Mon Sep 17 00:00:00 2001 From: alejandro Date: Wed, 27 Nov 2024 14:44:54 -0500 Subject: [PATCH 2/3] feat: adding built-in summarization tool for synthesizing cortex search outputs when needed --- Quickstart.ipynb | 788 +++++++++++++------------ agent_gateway/gateway/output_parser.py | 5 +- 2 files changed, 402 insertions(+), 391 deletions(-) diff --git a/Quickstart.ipynb b/Quickstart.ipynb index 24453a7..28ecf84 100644 --- a/Quickstart.ipynb +++ b/Quickstart.ipynb @@ -1,392 +1,402 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Agent Gateway Quickstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Agent Gateway is a multi-agent framework that offers native support for Snowflake tools. \n", - "\n", - "The system can be configured to work with 3 types of tools:\n", - "- Cortex Search Tool: For unstructured data analysis, which requires a standard RAG access pattern.\n", - "- Cortex Analyst Tool: For supporting structured data analysis, which requires a Text2SQL access pattern.\n", - "- Python Tool: For supporting custom user operations (using 3rd Party API's), which requires calling arbitrary python.\n", - "\n", - "This notebook walks through how to configure and run a system with all 3 types of tools. The demo is designed to illustrate how the agent can answer questions that require a divserse combination of tools (RAG,Text2SQL, Python, or a combination).\n", - "\n", - "Note that Agent Gateway does not configure the underlying Cortex Search or Cortex Analyst services for the user. Those services must be configured before initializing the agent." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Agent Configuration" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Connection Setup" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Authenticate with Snowpark + set token as environment variable for use by the agents." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from agent_gateway import Agent\n", - "from agent_gateway.tools import CortexSearchTool, CortexAnalystTool, PythonTool\n", - "from snowflake.snowpark import Session\n", - "import os, time\n", - "\n", - "connection_parameters = {\n", - " \"account\": os.getenv(\"SNOWFLAKE_ACCOUNT\"),\n", - " \"user\": os.getenv(\"SNOWFLAKE_USER\"),\n", - " \"password\": os.getenv(\"SNOWFLAKE_PASSWORD\"),\n", - " \"role\": os.getenv(\"SNOWFLAKE_ROLE\"),\n", - " \"warehouse\": os.getenv(\"SNOWFLAKE_WAREHOUSE\"),\n", - " \"database\": os.getenv(\"SNOWFLAKE_DATABASE\"),\n", - " \"schema\": os.getenv(\"SNOWFLAKE_SCHEMA\"),\n", - "}\n", - "\n", - "snowpark = Session.builder.configs(connection_parameters).create()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Snowflake Tool Configuration" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Cortex Search Tool and the Cortex Analyst Tool need to be configured as follows. Note that a connection object is required for each config. In the case below we're using the same connection object for both because the services are both in the same account/database/schema. Users have the option to pass in different connection objects as needed." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "search_config = {\n", - " \"service_name\": \"SEC_SEARCH_SERVICE\",\n", - " \"service_topic\": \"Snowflake's business,product offerings,and performance.\",\n", - " \"data_description\": \"Snowflake annual reports\",\n", - " \"retrieval_columns\": [\"CHUNK\"],\n", - " \"snowflake_connection\": snowpark,\n", - "}\n", - "\n", - "analyst_config = {\n", - " \"semantic_model\": \"sp500_semantic_model.yaml\",\n", - " \"stage\": \"ANALYST\",\n", - " \"service_topic\": \"S&P500 company and stock metrics\",\n", - " \"data_description\": \"a table with stock and financial metrics about S&P500 companies \",\n", - " \"snowflake_connection\": snowpark,\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Python Tool Configuration" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Configuring a Python Tool for the Agent Gateway requires 1) Python Callable 2) Tool Description (what does the tool do) 3) Output Description (what does the tool output). \n", - "\n", - "In the example below we create a NewsTool object that submits a HTTP request to a 3rd Party News API. The python callable is passed into the Python Tool as `news_api_func`.To use the tool below get your free token by signing up for an account at thenewsapi.com or just create your own python function and pass it into the PythonTool." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "import requests, json\n", - "\n", - "\n", - "class NewsTool:\n", - " def __init__(self, token, limit) -> None:\n", - " self.api_token = token\n", - " self.limit = limit\n", - "\n", - " def news_search(self, news_query: str) -> str:\n", - " news_request = f\"\"\"https://api.thenewsapi.com/v1/news/all?api_token={self.api_token}&search={news_query}&language=en&limit={self.limit}\"\"\"\n", - " response = requests.get(news_request)\n", - " json_response = json.loads(response.content)[\"data\"]\n", - "\n", - " return str(json_response)\n", - "\n", - "\n", - "python_config = {\n", - " \"tool_description\": \"searches for relevant news based on user query\",\n", - " \"output_description\": \"relevant articles\",\n", - " \"python_func\": NewsTool(token=os.getenv(\"NEWS_API_TOKEN\"), limit=3).news_search,\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Agent Config" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After the tools have been configured, initialize them and configure the agent." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:AgentGatewayLogger:Cortex Search Tool successfully initialized\n", - "INFO:AgentGatewayLogger:Cortex Analyst Tool successfully initialized\n", - "INFO:AgentGatewayLogger:Python Tool successfully initialized\n", - "INFO:AgentGatewayLogger:Cortex gateway successfully initialized\n" - ] - } - ], - "source": [ - "annual_reports = CortexSearchTool(**search_config)\n", - "sp500 = CortexAnalystTool(**analyst_config)\n", - "news_search = PythonTool(**python_config)\n", - "\n", - "snowflake_tools = [annual_reports, sp500, news_search]\n", - "agent = Agent(snowflake_connection=snowpark, tools=snowflake_tools)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Agent Testing" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The 3 types of questions below are designed to showcase the breadth of tool use patterns possible with the Agent Gateway. \n", - "\n", - "- The Structured Data Questions use the Cortex Analyst agent. \n", - "- The Unstructured Data Questions use either the Cortex Search agent or the Python (News API) agent.\n", - "- The last section includes a question that requires the use of both types of tools." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Structured Data Questions" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:AgentGatewayLogger:running sp500_semantic_model_cortexanalyst task\n" - ] - }, - { - "data": { - "text/plain": [ - "'The market cap of Apple is $3,019,131,060,224 or approximately $3.02 trillion.'" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agent(\"What is the market cap of Apple?\")" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:AgentGatewayLogger:running sp500_semantic_model_cortexanalyst task\n", - "INFO:AgentGatewayLogger:running sp500_semantic_model_cortexanalyst task\n" - ] - }, - { - "data": { - "text/plain": [ - "'Apple has a bigger EBITDA than Microsoft.'" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agent(\"Which company has the bigger EBITDA, Apple or MSFT?\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Unstructured Data Questions" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:AgentGatewayLogger:running sec_search_service_cortexsearch task\n" - ] - }, - { - "data": { - "text/plain": [ - "'As of January 31, 2024, Snowflake had 9,437 total customers.'" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agent(\"How many customers does Snowflake have?\")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:AgentGatewayLogger:running news_search task\n" - ] - }, - { - "data": { - "text/plain": [ - "'\\'Recent news about Azure\\'s AI investments includes:\\\\n- Article: \"Microsoft\\'s SWOT analysis: azure growth, ai investments shape stock outlook\" Source: [Investing.com](https://www.investing.com/news/company-news/microsofts-swot-analysis-azure-growth-ai-investments-shape-stock-outlook-93CH-3701643)\\\\n- Article: \"AI Investments: Key Driver for MSFT and META Earnings\" Source: [GuruFocus](https://www.gurufocus.com/news/2573539/ai-investments-key-driver-for-msft-and-meta-earnings)\\\\n- Article: \"Microsoft: Navigating AI Investments Amid Market Volatility\" Source: [GuruFocus](https://www.gurufocus.com/news/2499558/microsoft-navigating-ai-investments-amid-market-volatility)'" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agent(\"Give me recent news about Azure's AI investments\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Unstructured + Structured Data Questions" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:AgentGatewayLogger:running sp500_semantic_model_cortexanalyst task\n", - "INFO:AgentGatewayLogger:running sec_search_service_cortexsearch task\n" - ] - }, - { - "data": { - "text/plain": [ - "\"The 5 biggest companies in the S&P500 by market cap are Microsoft Corporation, Apple Inc., NVIDIA Corporation, Alphabet Inc., and Amazon.com, Inc. None of these companies are referenced in the provided sections of Snowflake's annual report.\"" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agent(\n", - " \"What are the 5 biggest companies in the S&P500 by market cap? Are any of them referenced in Snowflake's annual report?\"\n", - ")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": ".venv", - "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.6" - } + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Agent Gateway Quickstart" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Agent Gateway is a multi-agent framework that offers native support for Snowflake tools. \n", + "\n", + "The system can be configured to work with 3 types of tools:\n", + "- Cortex Search Tool: For unstructured data analysis, which requires a standard RAG access pattern.\n", + "- Cortex Analyst Tool: For supporting structured data analysis, which requires a Text2SQL access pattern.\n", + "- Python Tool: For supporting custom user operations (using 3rd Party API's), which requires calling arbitrary python.\n", + "\n", + "This notebook walks through how to configure and run a system with all 3 types of tools. The demo is designed to illustrate how the agent can answer questions that require a divserse combination of tools (RAG,Text2SQL, Python, or a combination).\n", + "\n", + "Note that Agent Gateway does not configure the underlying Cortex Search or Cortex Analyst services for the user. Those services must be configured before initializing the agent." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Agent Configuration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Connection Setup" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Authenticate with Snowpark + set token as environment variable for use by the agents." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/alherrera/Downloads/Cube/cortex-cube/.venv/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n" + ] + } + ], + "source": [ + "from agent_gateway import Agent\n", + "from agent_gateway.tools import CortexSearchTool, CortexAnalystTool, PythonTool\n", + "from snowflake.snowpark import Session\n", + "import os, time\n", + "\n", + "connection_parameters = {\n", + " \"account\": os.getenv(\"SNOWFLAKE_ACCOUNT\"),\n", + " \"user\": os.getenv(\"SNOWFLAKE_USER\"),\n", + " \"password\": os.getenv(\"SNOWFLAKE_PASSWORD\"),\n", + " \"role\": os.getenv(\"SNOWFLAKE_ROLE\"),\n", + " \"warehouse\": os.getenv(\"SNOWFLAKE_WAREHOUSE\"),\n", + " \"database\": os.getenv(\"SNOWFLAKE_DATABASE\"),\n", + " \"schema\": os.getenv(\"SNOWFLAKE_SCHEMA\"),\n", + "}\n", + "\n", + "snowpark = Session.builder.configs(connection_parameters).create()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Snowflake Tool Configuration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Cortex Search Tool and the Cortex Analyst Tool need to be configured as follows. Note that a connection object is required for each config. In the case below we're using the same connection object for both because the services are both in the same account/database/schema. Users have the option to pass in different connection objects as needed." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "search_config = {\n", + " \"service_name\": \"SEC_SEARCH_SERVICE\",\n", + " \"service_topic\": \"Snowflake's business,product offerings,and performance.\",\n", + " \"data_description\": \"Snowflake annual reports\",\n", + " \"retrieval_columns\": [\"CHUNK\"],\n", + " \"snowflake_connection\": snowpark,\n", + "}\n", + "\n", + "analyst_config = {\n", + " \"semantic_model\": \"sp500_semantic_model.yaml\",\n", + " \"stage\": \"ANALYST\",\n", + " \"service_topic\": \"S&P500 company and stock metrics\",\n", + " \"data_description\": \"a table with stock and financial metrics about S&P500 companies \",\n", + " \"snowflake_connection\": snowpark,\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Python Tool Configuration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Configuring a Python Tool for the Agent Gateway requires 1) Python Callable 2) Tool Description (what does the tool do) 3) Output Description (what does the tool output). \n", + "\n", + "In the example below we create a NewsTool object that submits a HTTP request to a 3rd Party News API. The python callable is passed into the Python Tool as `news_api_func`.To use the tool below get your free token by signing up for an account at thenewsapi.com or just create your own python function and pass it into the PythonTool." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import requests, json\n", + "\n", + "\n", + "class NewsTool:\n", + " def __init__(self, token, limit) -> None:\n", + " self.api_token = token\n", + " self.limit = limit\n", + "\n", + " def news_search(self, news_query: str) -> str:\n", + " news_request = f\"\"\"https://api.thenewsapi.com/v1/news/all?api_token={self.api_token}&search={news_query}&language=en&limit={self.limit}\"\"\"\n", + " response = requests.get(news_request)\n", + " json_response = json.loads(response.content)[\"data\"]\n", + "\n", + " return str(json_response)\n", + "\n", + "\n", + "python_config = {\n", + " \"tool_description\": \"searches for relevant news based on user query\",\n", + " \"output_description\": \"relevant articles\",\n", + " \"python_func\": NewsTool(token=os.getenv(\"NEWS_API_TOKEN\"), limit=3).news_search,\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Agent Config" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After the tools have been configured, initialize them and configure the agent." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:AgentGatewayLogger:Cortex Search Tool successfully initialized\n", + "INFO:AgentGatewayLogger:Cortex Analyst Tool successfully initialized\n", + "INFO:AgentGatewayLogger:Python Tool successfully initialized\n", + "INFO:AgentGatewayLogger:Cortex gateway successfully initialized\n" + ] + } + ], + "source": [ + "annual_reports = CortexSearchTool(**search_config)\n", + "sp500 = CortexAnalystTool(**analyst_config)\n", + "news_search = PythonTool(**python_config)\n", + "\n", + "snowflake_tools = [annual_reports, sp500, news_search]\n", + "agent = Agent(snowflake_connection=snowpark, tools=snowflake_tools)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Agent Testing" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The 3 types of questions below are designed to showcase the breadth of tool use patterns possible with the Agent Gateway. \n", + "\n", + "- The Structured Data Questions use the Cortex Analyst agent. \n", + "- The Unstructured Data Questions use either the Cortex Search agent or the Python (News API) agent.\n", + "- The last section includes a question that requires the use of both types of tools." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Structured Data Questions" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:AgentGatewayLogger:running sp500_semantic_model_cortexanalyst task\n" + ] }, - "nbformat": 4, - "nbformat_minor": 2 + { + "data": { + "text/plain": [ + "'The market cap of Apple is $3,019,131,060,224 or approximately $3.02 trillion.'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "agent(\"What is the market cap of Apple?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:AgentGatewayLogger:running sp500_semantic_model_cortexanalyst task\n", + "INFO:AgentGatewayLogger:running sp500_semantic_model_cortexanalyst task\n" + ] + }, + { + "data": { + "text/plain": [ + "'Apple has a bigger EBITDA than Microsoft.'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "agent(\"Which company has the bigger EBITDA, Apple or MSFT?\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Unstructured Data Questions" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:AgentGatewayLogger:running sec_search_service_cortexsearch task\n" + ] + }, + { + "data": { + "text/plain": [ + "'As of January 31, 2024, Snowflake had 9,437 total customers.'" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "agent(\"How many customers does Snowflake have?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:AgentGatewayLogger:running news_search task\n" + ] + }, + { + "data": { + "text/plain": [ + "'\\'Recent news about Azure\\'s AI investments includes:\\\\n- Article: \"Microsoft\\'s SWOT analysis: azure growth, ai investments shape stock outlook\" Source: [Investing.com](https://www.investing.com/news/company-news/microsofts-swot-analysis-azure-growth-ai-investments-shape-stock-outlook-93CH-3701643)\\\\n- Article: \"AI Investments: Key Driver for MSFT and META Earnings\" Source: [GuruFocus](https://www.gurufocus.com/news/2573539/ai-investments-key-driver-for-msft-and-meta-earnings)\\\\n- Article: \"Microsoft: Navigating AI Investments Amid Market Volatility\" Source: [GuruFocus](https://www.gurufocus.com/news/2499558/microsoft-navigating-ai-investments-amid-market-volatility)'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "agent(\"Give me recent news about Azure's AI investments\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unstructured + Structured Data Questions" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:AgentGatewayLogger:running sec_search_service_cortexsearch task\n", + "INFO:AgentGatewayLogger:running summarize task\n", + "INFO:AgentGatewayLogger:running sp500_semantic_model_cortexanalyst task\n" + ] + }, + { + "data": { + "text/plain": [ + "\"The market cap of Snowflake's competitors in the S&P500 are: Microsoft Corporation ($3,150,184,448,000), Alphabet Inc. ($2,164,350,779,392), Amazon.com, Inc. ($1,917,936,336,896), and Oracle Corporation ($346,092,371,968).\"" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "agent(\n", + " \"Which S&P500 companies are considered competitors in Snowflake's annual report? What is the market cap of each company mentioned?\"\n", + ")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "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.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/agent_gateway/gateway/output_parser.py b/agent_gateway/gateway/output_parser.py index 9fe6395..30f27b9 100644 --- a/agent_gateway/gateway/output_parser.py +++ b/agent_gateway/gateway/output_parser.py @@ -91,12 +91,13 @@ def _initialize_task_list(matches): def _create_summarization_step(context, index): - summarization_prompt = f"Think step by step in order to give me {context} using the following context: ${index}" + summarization_prompt = f"Concisely give me {context} ONLY using the following context: ${index}. DO NOT include any other rationale." return ( "I need to concisely summarize the cortex search output", str(index + 1), "summarize", summarization_prompt, + "", ) @@ -107,7 +108,7 @@ def _update_task_references(task, index_mapping): lambda m: f"${index_mapping.get(m.group(1), m.group(1))}", updated_string, ) - return (task[0], task[1], task[2], updated_string) + return (task[0], task[1], task[2], updated_string, "") def _update_task_list_with_summarization(matches): From b5ebe3f8ff84100ac8d7c156c2b81871dbe9d2a5 Mon Sep 17 00:00:00 2001 From: Alejandro Herrera <149527975+sfc-gh-alherrera@users.noreply.github.com> Date: Wed, 27 Nov 2024 20:00:57 -0500 Subject: [PATCH 3/3] Update agent_gateway/gateway/planner.py Co-authored-by: Tyler White --- agent_gateway/gateway/planner.py | 1 - 1 file changed, 1 deletion(-) diff --git a/agent_gateway/gateway/planner.py b/agent_gateway/gateway/planner.py index 2dc006e..2fd0c51 100644 --- a/agent_gateway/gateway/planner.py +++ b/agent_gateway/gateway/planner.py @@ -230,7 +230,6 @@ def __init__( example_prompt=example_prompt_replan, is_replan=True, ) - # self.tools = tools self.output_parser = GatewayPlanParser(tools=tools) self.stop = stop