{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# ClimateQ&A\n", "---\n", "Goal of the notebook: Recommended graphs functionality\n", "\n", "Inputs of the notebook:\n", "\n", "Output of the notebook:\n", "\n", "\n", "Takeaways:\n", "\n", "Questions, thoughts and remarks:\n", "- What do I put for query instruction ?\n", " - Default is \"Represent this sentence for searching relevant passages:\"\n", " - embedding_function = get_embeddings_function(query_instruction=\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dependencies and path\n", "Adjust the argument in `sys.path.append` to align with your specific requirements." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd \n", "import numpy as np\n", "import os\n", "from IPython.display import display, Markdown\n", "\n", "%load_ext autoreload\n", "%autoreload 2\n", "\n", "ROOT_DIR = os.path.dirname(os.getcwd())\n", "\n", "import sys\n", "sys.path.append(\"/home/dora/climate-question-answering\")\n", "sys.path.append(ROOT_DIR)\n", "\n", "from dotenv import load_dotenv\n", "load_dotenv()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Import objects\n", "### 1.1 LLM" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from climateqa.engine.llm import get_llm\n", "llm = get_llm(provider=\"openai\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.2 Embedding" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading embeddings model: BAAI/bge-base-en-v1.5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/home/tim/anaconda3/envs/climateqa/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 climateqa.engine.embeddings import get_embeddings_function\n", "\n", "embeddings_function = get_embeddings_function()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.3 Reranker" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading FlashRankRanker model ms-marco-TinyBERT-L-2-v2\n", "Loading model FlashRank model ms-marco-TinyBERT-L-2-v2...\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from climateqa.engine.reranker import get_reranker\n", "\n", "reranker = get_reranker(\"nano\")\n", "reranker" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.4 IPCC vectorstore" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/tim/ai4s/climate_qa/climate-question-answering/climateqa/engine/vectorstore.py:38: LangChainDeprecationWarning: The class `Pinecone` was deprecated in LangChain 0.0.18 and will be removed in 0.3.0. An updated version of the class exists in the langchain-pinecone package and should be used instead. To use it run `pip install -U langchain-pinecone` and import as `from langchain_pinecone import Pinecone`.\n", " vectorstore = PineconeVectorstore(\n" ] } ], "source": [ "from climateqa.engine.vectorstore import get_pinecone_vectorstore\n", "\n", "vectorstore = get_pinecone_vectorstore(embeddings_function)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2 Vectorstore" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.1 IEA data" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
titlereturned_contentsourcesnotesappears_inappears_in_urldoc_idsource
0Capital requirements for mining to meet demand...https://www.iea.org/data-and-statistics/charts...IEA analysis based on data from S&P Global and...Capital requirements are calculated based on c...Global Critical Minerals Outlook 2024https://www.iea.org/reports/global-critical-mi...iea_0IEA
1IEA energy transition mineral price index, Jan...https://www.iea.org/data-and-statistics/charts...IEA analysis based on Bloomberg and S&P Global.IEA energy transition minerals price index is ...Global Critical Minerals Outlook 2024https://www.iea.org/reports/global-critical-mi...iea_1IEA
2Price developments of minerals and metals by c...https://www.iea.org/data-and-statistics/charts...IEA analysis based on Bloomberg and S&P Global.Base metals include iron, aluminium, zinc and ...Global Critical Minerals Outlook 2024https://www.iea.org/reports/global-critical-mi...iea_2IEA
3Capital expenditure on nonferrous metal produc...https://www.iea.org/data-and-statistics/charts...IEA analysis based on company annual reports a...For diversified majors, capex on the productio...Global Critical Minerals Outlook 2024https://www.iea.org/reports/global-critical-mi...iea_3IEA
4Selected environmental, social and governance ...https://www.iea.org/data-and-statistics/charts...IEA analysis based on the latest sustainabilit...GHG= greenhouse gas. Aggregated data for 25 ma...Global Critical Minerals Outlook 2024https://www.iea.org/reports/global-critical-mi...iea_4IEA
\n", "
" ], "text/plain": [ " title \\\n", "0 Capital requirements for mining to meet demand... \n", "1 IEA energy transition mineral price index, Jan... \n", "2 Price developments of minerals and metals by c... \n", "3 Capital expenditure on nonferrous metal produc... \n", "4 Selected environmental, social and governance ... \n", "\n", " returned_content \\\n", "0 https://www.iea.org/data-and-statistics/charts... \n", "1 https://www.iea.org/data-and-statistics/charts... \n", "2 https://www.iea.org/data-and-statistics/charts... \n", "3 https://www.iea.org/data-and-statistics/charts... \n", "4 https://www.iea.org/data-and-statistics/charts... \n", "\n", " sources \\\n", "0 IEA analysis based on data from S&P Global and... \n", "1 IEA analysis based on Bloomberg and S&P Global. \n", "2 IEA analysis based on Bloomberg and S&P Global. \n", "3 IEA analysis based on company annual reports a... \n", "4 IEA analysis based on the latest sustainabilit... \n", "\n", " notes \\\n", "0 Capital requirements are calculated based on c... \n", "1 IEA energy transition minerals price index is ... \n", "2 Base metals include iron, aluminium, zinc and ... \n", "3 For diversified majors, capex on the productio... \n", "4 GHG= greenhouse gas. Aggregated data for 25 ma... \n", "\n", " appears_in \\\n", "0 Global Critical Minerals Outlook 2024 \n", "1 Global Critical Minerals Outlook 2024 \n", "2 Global Critical Minerals Outlook 2024 \n", "3 Global Critical Minerals Outlook 2024 \n", "4 Global Critical Minerals Outlook 2024 \n", "\n", " appears_in_url doc_id source \n", "0 https://www.iea.org/reports/global-critical-mi... iea_0 IEA \n", "1 https://www.iea.org/reports/global-critical-mi... iea_1 IEA \n", "2 https://www.iea.org/reports/global-critical-mi... iea_2 IEA \n", "3 https://www.iea.org/reports/global-critical-mi... iea_3 IEA \n", "4 https://www.iea.org/reports/global-critical-mi... iea_4 IEA " ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from langchain_community.document_loaders import DataFrameLoader\n", "from langchain_chroma import Chroma\n", "\n", "df_iea = pd.read_csv(f\"{ROOT_DIR}/data/charts_iea.csv\")\n", "df_iea = df_iea.rename(columns={'url': 'returned_content'})\n", "df_iea[\"doc_id\"] = \"iea_\" + df_iea.index.astype(str)\n", "df_iea[\"source\"] = \"IEA\"\n", "df_iea.head()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5355" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Load csv file of charts\n", "loader_iea = DataFrameLoader(df_iea, page_content_column='title')\n", "documents_iea = loader_iea.load()\n", "len(documents_iea)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.2 OWID data" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
categorytitleurlreturned_contentsubtitledoc_idsource
0Access to EnergyNumber of people with and without access to cl...https://ourworldindata.org/grapher/number-with...<iframe src=\"https://ourworldindata.org/graphe...Clean cooking fuels and technologies represent...owid_0OWID
1Access to EnergyNumber of people without access to clean fuels...https://ourworldindata.org/grapher/number-with...<iframe src=\"https://ourworldindata.org/graphe...Clean cooking fuels and technologies represent...owid_1OWID
2Access to EnergyPeople without clean fuels for cooking, by wor...https://ourworldindata.org/grapher/people-with...<iframe src=\"https://ourworldindata.org/graphe...Data source: World Bankowid_2OWID
3Access to EnergyShare of the population without access to clea...https://ourworldindata.org/grapher/share-of-th...<iframe src=\"https://ourworldindata.org/graphe...Access to clean fuels or technologies such as ...owid_3OWID
4Access to EnergyShare with access to electricity vs. per capit...https://ourworldindata.org/grapher/share-with-...<iframe src=\"https://ourworldindata.org/graphe...Having access to electricity is defined in int...owid_4OWID
\n", "
" ], "text/plain": [ " category title \\\n", "0 Access to Energy Number of people with and without access to cl... \n", "1 Access to Energy Number of people without access to clean fuels... \n", "2 Access to Energy People without clean fuels for cooking, by wor... \n", "3 Access to Energy Share of the population without access to clea... \n", "4 Access to Energy Share with access to electricity vs. per capit... \n", "\n", " url \\\n", "0 https://ourworldindata.org/grapher/number-with... \n", "1 https://ourworldindata.org/grapher/number-with... \n", "2 https://ourworldindata.org/grapher/people-with... \n", "3 https://ourworldindata.org/grapher/share-of-th... \n", "4 https://ourworldindata.org/grapher/share-with-... \n", "\n", " returned_content \\\n", "0 ', 'subtitle': 'Total area of forests, savannas, shrublands/grasslands, croplands, and other land that have been burned as a result of wildfires each year.', 'doc_id': 'owid_2201', 'source': 'OWID'}, page_content='Wildfire area burned by land cover type')" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "documents_all[-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.4 Chroma vectorstore" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:chromadb.telemetry.posthog:Anonymized telemetry enabled. See https://docs.trychroma.com/telemetry for more information.\n", "INFO:chromadb.telemetry.posthog:Anonymized telemetry enabled. See https://docs.trychroma.com/telemetry for more information.\n" ] } ], "source": [ "# DO NOT RUN AGAIN (persisted)\n", "# vectorstore_graphs = Chroma.from_documents(documents_all, embeddings_function, persist_directory=f\"{ROOT_DIR}/data/vectorstore\")\n", "# vectorstore_graphs = Chroma.from_documents(documents_owid, embeddings_function, persist_directory=f\"{ROOT_DIR}/data/vectorstore_owid\")" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:chromadb.telemetry.posthog:Anonymized telemetry enabled. See https://docs.trychroma.com/telemetry for more information.\n" ] } ], "source": [ "from langchain_chroma import Chroma\n", "\n", "vectorstore_graphs = Chroma(persist_directory=f\"{ROOT_DIR}/data/vectorstore_owid\", embedding_function=embeddings_function)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(Document(metadata={'category': 'Water Use & Stress', 'doc_id': 'owid_2184', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Water quality is assessed by means of core physical and chemical parameters that reflect natural water quality. A water body is classified as \"good\" quality if at least 80% of monitoring values meet target quality levels.', 'url': 'https://ourworldindata.org/grapher/water-bodies-good-water-quality'}, page_content='Share of water bodies with good ambient water quality'),\n", " 0.46955257728383504),\n", " (Document(metadata={'category': 'Clean Water & Sanitation', 'doc_id': 'owid_742', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Water quality is assessed by means of core physical and chemical parameters that reflect natural water quality. A water body is classified as \"good\" quality if at least 80% of monitoring values meet target quality levels.', 'url': 'https://ourworldindata.org/grapher/water-bodies-good-water-quality'}, page_content='Share of water bodies with good ambient water quality'),\n", " 0.46955245084328956),\n", " (Document(metadata={'category': 'Water Pollution', 'doc_id': 'owid_2151', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Water quality is assessed by means of core physical and chemical parameters that reflect natural water quality. A water body is classified as \"good\" quality if at least 80% of monitoring values meet target quality levels.', 'url': 'https://ourworldindata.org/grapher/water-bodies-good-water-quality'}, page_content='Share of water bodies with good ambient water quality'),\n", " 0.46955245084328956),\n", " (Document(metadata={'category': 'Clean Water', 'doc_id': 'owid_667', 'returned_content': '', 'source': 'OWID', 'subtitle': 'A basic drinking water service is water from an improved water source that can be collected within a 30-minute round trip, including queuing.', 'url': 'https://ourworldindata.org/grapher/population-using-at-least-basic-drinking-water'}, page_content='Share of population using at least a basic drinking water source'),\n", " 0.43011969078910306)]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vectorstore_graphs.similarity_search_with_relevance_scores(\"What is the trend of clean water?\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Retriever for recommended graphs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.1 Custom retriever" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "from langchain_core.retrievers import BaseRetriever\n", "from langchain_core.documents.base import Document\n", "from langchain_core.vectorstores import VectorStore\n", "from langchain_core.callbacks.manager import CallbackManagerForRetrieverRun\n", "\n", "from typing import List\n", "\n", "class GraphRetriever(BaseRetriever):\n", " vectorstore:VectorStore\n", " sources:list = [\"IEA\", \"OWID\"] # plus tard ajouter OurWorldInData # faudra integrate avec l'autre retriever\n", " threshold:float = 0.5\n", " k_total:int = 10\n", "\n", " def _get_relevant_documents(\n", " self, query: str, *, run_manager: CallbackManagerForRetrieverRun\n", " ) -> List[Document]:\n", "\n", " # Check if all elements in the list are IEA or OWID\n", " assert isinstance(self.sources,list)\n", " assert any([x in [\"IEA\", \"OWID\"] for x in self.sources])\n", "\n", " # Prepare base search kwargs\n", " filters = {}\n", "\n", " filters[\"source\"] = {\"$in\": self.sources}\n", "\n", " docs = self.vectorstore.similarity_search_with_score(query=query, filter=filters, k=self.k_total)\n", " \n", " # Filter if scores are below threshold\n", " docs = [x for x in docs if x[1] > self.threshold]\n", "\n", " # Add score to metadata\n", " results = []\n", " for i,(doc,score) in enumerate(docs):\n", " doc.metadata[\"similarity_score\"] = score\n", " doc.metadata[\"content\"] = doc.page_content\n", " results.append(doc)\n", "\n", " return results" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "retriever = GraphRetriever(vectorstore=vectorstore_graphs)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[Document(metadata={'category': 'Energy', 'doc_id': 'owid_969', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Energy trade, measured as the percentage of energy use. Positive values indicate a country or region is a net importer of energy. Negative numbers indicate a country or region is a net exporter.', 'url': 'https://ourworldindata.org/grapher/energy-imports-and-exports-energy-use', 'similarity_score': 0.7722029089927673, 'content': 'Energy imports and exports'}, page_content='Energy imports and exports'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_400', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Environmentally sound technologies (ESTs) are technologies that have the potential for significantly improved environmental performance relative to other technologies. This indicator shows the value of imported ESTs in current US-$.', 'url': 'https://ourworldindata.org/grapher/import-of-environmentally-sound-technologies', 'similarity_score': 0.782991886138916, 'content': 'Import of environmentally sound technologies'}, page_content='Import of environmentally sound technologies'),\n", " Document(metadata={'category': 'Energy', 'doc_id': 'owid_1013', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Share of primary energy by source over the long-term, measured as the percentage of total energy consumption. Primary electricity includes: hydropower, nuclear power, wind, photo\\xadvoltaics, tidal, wave and solar thermal and geothermal (only figures for electricity production are included).', 'url': 'https://ourworldindata.org/grapher/long-term-energy-transitions', 'similarity_score': 0.8692131638526917, 'content': 'Long-term energy transitions'}, page_content='Long-term energy transitions'),\n", " Document(metadata={'category': 'Forests & Deforestation', 'doc_id': 'owid_1376', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Imported deforestation is the amount of deforestation in other countries that is driven by the production of food and forestry products that are imported. This is measured in hectares.', 'url': 'https://ourworldindata.org/grapher/imported-deforestation', 'similarity_score': 0.8846064805984497, 'content': 'Imported deforestation'}, page_content='Imported deforestation'),\n", " Document(metadata={'category': 'Energy', 'doc_id': 'owid_1019', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Net electricity imports are calculated as electricity imports minus exports. Countries with positive values are net importers of electricity; negative values are net exporters. Measured in terawatt-hours.', 'url': 'https://ourworldindata.org/grapher/net-electricity-imports', 'similarity_score': 0.8954001069068909, 'content': 'Net electricity imports'}, page_content='Net electricity imports'),\n", " Document(metadata={'category': 'Energy', 'doc_id': 'owid_983', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Total fossil fuel production - differentiated by coal, oil and natural gas - by country over the long-run, measured in terawatt-hour (TWh) equivalents per year.', 'url': 'https://ourworldindata.org/grapher/fossil-fuel-production-over-the-long-term', 'similarity_score': 0.9086273312568665, 'content': 'Fossil fuel production over the long-term'}, page_content='Fossil fuel production over the long-term'),\n", " Document(metadata={'category': 'Fossil Fuels', 'doc_id': 'owid_1443', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Total fossil fuel production - differentiated by coal, oil and natural gas - by country over the long-run, measured in terawatt-hour (TWh) equivalents per year.', 'url': 'https://ourworldindata.org/grapher/fossil-fuel-production-over-the-long-term', 'similarity_score': 0.9086273312568665, 'content': 'Fossil fuel production over the long-term'}, page_content='Fossil fuel production over the long-term'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_379', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Environmentally sound technologies (ESTs) are technologies that have the potential for significantly improved environmental performance relative to other technologies. This indicator shows the value of exported ESTs in current US-$.', 'url': 'https://ourworldindata.org/grapher/export-of-environmentally-sound-technologies', 'similarity_score': 0.9094725847244263, 'content': 'Export of environmentally sound technologies'}, page_content='Export of environmentally sound technologies'),\n", " Document(metadata={'category': 'Electricity Mix', 'doc_id': 'owid_892', 'returned_content': '', 'source': 'OWID', 'subtitle': \"Net electricity imports are calculated as electricity imports minus exports. This is given as a share of a country's electricity demand. Countries with positive values are net importers of electricity; negative values are net exporters.\", 'url': 'https://ourworldindata.org/grapher/electricity-imports-share-demand', 'similarity_score': 0.9217990636825562, 'content': 'Net electricity imports as a share of electricity demand'}, page_content='Net electricity imports as a share of electricity demand'),\n", " Document(metadata={'category': 'Energy', 'doc_id': 'owid_1020', 'returned_content': '', 'source': 'OWID', 'subtitle': \"Net electricity imports are calculated as electricity imports minus exports. This is given as a share of a country's electricity demand. Countries with positive values are net importers of electricity; negative values are net exporters.\", 'url': 'https://ourworldindata.org/grapher/electricity-imports-share-demand', 'similarity_score': 0.9217990636825562, 'content': 'Net electricity imports as a share of electricity demand'}, page_content='Net electricity imports as a share of electricity demand')]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=293793a6-6cdd-4e70-ba2d-c1211936330a,id=293793a6-6cdd-4e70-ba2d-c1211936330a\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=83bce3ac-3941-4868-b904-954796b2c87b,id=83bce3ac-3941-4868-b904-954796b2c87b; trace=83bce3ac-3941-4868-b904-954796b2c87b,id=a1e66cdf-541e-45be-a04e-0273eb464bd0; trace=83bce3ac-3941-4868-b904-954796b2c87b,id=aae4ff52-19c8-4d68-8cf3-aa5ef96d90a9\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=83bce3ac-3941-4868-b904-954796b2c87b,id=89c9ee4d-0531-40b3-b7d5-471f2d1d7f72; patch: trace=83bce3ac-3941-4868-b904-954796b2c87b,id=83bce3ac-3941-4868-b904-954796b2c87b; trace=83bce3ac-3941-4868-b904-954796b2c87b,id=aae4ff52-19c8-4d68-8cf3-aa5ef96d90a9\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=2f60f3cb-8969-43c1-9be6-a38da876bbeb; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=8abe438d-b623-444e-acf0-01cbe05204d2; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=9641fded-8e17-440c-9be4-651bcf1e62f8; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=dcb0920c-68a9-4663-8f0f-b8d9bb91d9e8; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=be55ec0c-6a79-410b-8fdd-006518ef4839; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=e69b8a0c-353f-4cca-a888-bc92c1ab80e8\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=5c8a1a4d-cf91-47a4-a1d1-29def2a546f8; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=80fcf03e-55a9-4910-bf68-773e94166b87; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=c55b0d31-4534-4e79-a7dd-9e41e8b60d6f; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=ab9e5151-57c0-47b7-9227-1af10c6edd4d; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=36341116-242a-4979-a0a6-3c6e264213d2; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=19e3b604-d805-4e71-9bb5-040d2fd6ab17; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=720a713f-2ea5-4912-81ac-727205915326; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=cdd69060-8047-44d3-9340-a9523d4a9fd7; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=7cb77350-949b-4800-88fe-cdb91e181a6f; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=e6af6666-4615-453b-9b06-f48e85f7ec0b; patch: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=dcb0920c-68a9-4663-8f0f-b8d9bb91d9e8; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=e69b8a0c-353f-4cca-a888-bc92c1ab80e8; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=9641fded-8e17-440c-9be4-651bcf1e62f8\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=32397e1b-f5d9-4dbf-9e7a-ec51f6452023; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=2e0caf84-9662-4fea-a510-6b8d143dabdf; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=4c472c44-ac2c-4aa0-8931-22be0135d530; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=e332817e-ae69-4b92-9e50-05f9f77a410c; patch: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=cdd69060-8047-44d3-9340-a9523d4a9fd7; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=e6af6666-4615-453b-9b06-f48e85f7ec0b\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=4904b6c4-b677-4af4-8a6b-bf088dc8a6f9; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=c117d6db-6a45-4109-9579-5e609395bcae; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=d6c37d55-5e1d-47d1-bfd2-f56f58da3c83; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=e5d01647-1098-4ba5-b0be-5b7b6b086e1b; patch: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=e332817e-ae69-4b92-9e50-05f9f77a410c; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=2e0caf84-9662-4fea-a510-6b8d143dabdf\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=c3110852-8632-4f8d-a4a8-7c798b1cb1d9; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=b9823098-61d1-4aed-9f49-76e82571869c; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=c615dedd-9e6f-4250-96ea-c25184cd6a2c; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=0f9e226a-e351-4be0-b769-65ecf20b5de7; patch: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=c117d6db-6a45-4109-9579-5e609395bcae; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=e5d01647-1098-4ba5-b0be-5b7b6b086e1b; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=720a713f-2ea5-4912-81ac-727205915326\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=95c8f0b6-91ab-426f-b492-07d310b8fd2d; patch: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=0f9e226a-e351-4be0-b769-65ecf20b5de7\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=d39d0b70-ca46-4048-93f9-d60e7c66f60e; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=d4b8077e-99b9-496f-8ef3-a8adaf980fb4; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=3e7aa953-cc67-42f5-a46a-664d4aa61fe1; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=c55fad93-769c-4f5a-b716-80362f6bee24; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=31b02c82-76df-43c2-a276-c5bd8d1af58e; patch: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=95c8f0b6-91ab-426f-b492-07d310b8fd2d; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=c615dedd-9e6f-4250-96ea-c25184cd6a2c\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "patch: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=31b02c82-76df-43c2-a276-c5bd8d1af58e\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=af577682-c2ca-4730-aef8-815cd25be223; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=bed906a2-4e90-4737-ba3e-d073676f75ed; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=2932ab68-a73e-4471-a103-7ea64eb92015; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=be7246d2-b55c-4f1e-8805-c6caef632e9a; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=3791cee0-aba4-4f92-89b5-875af21e9dee; patch: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=3e7aa953-cc67-42f5-a46a-664d4aa61fe1; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=d4b8077e-99b9-496f-8ef3-a8adaf980fb4\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "patch: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=3791cee0-aba4-4f92-89b5-875af21e9dee\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=56ed1b23-c02d-45a9-89db-82ca85fc523f; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=badb4be6-7362-415c-8784-232b7a1710e7; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=62472c2f-e0f1-4cb9-910c-2263beedc8e0; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=b0830d8e-fdc7-470a-87d7-f70485289152; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=b6f642f0-0cfb-450c-9d96-8a0079d220cf; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=e3234978-eaf6-4046-970f-95e412aa889a; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=8aefd625-7233-4022-9f4b-58d8fabb9c43; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=fac8c029-5fb2-4dc8-9fb3-60f4ad9f3e85; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=dd5cc1ab-6ab5-4665-9d5c-37f957ba37eb; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=5ce47723-33ce-4237-91a1-55b885aef68c; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=a9e6125b-d5f6-4743-85b5-3eb2f087578d; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=1575bbfe-f738-4a87-8df8-c57e55435560; patch: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=2932ab68-a73e-4471-a103-7ea64eb92015; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=bed906a2-4e90-4737-ba3e-d073676f75ed\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=e8a28082-0011-4e85-a399-9bf6bebd6014; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=6b1a1120-0347-43b1-a0c3-16b53d9da843; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=c0f9923f-791b-4e31-875c-d70a3a7d918e; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=a5aae843-34b2-4f65-ba54-89f09509c737; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=84371741-fb6e-4dfe-9282-c969e3a5d190; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=829425fd-6030-4f2e-aef2-931a9f735554\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=47b58050-adb9-48b0-9c6e-b8a2e22e6123; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=fd05368e-94c9-492f-bc06-90bc13f848d6; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=41e95d82-9788-42e5-a38e-28c929f83208; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=c3480230-c4eb-4fd1-8208-325b22389052; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=0fc6ec9c-5086-4bac-a18d-d6a14eb38a35; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=63e8e2da-c4d9-45c0-b0d0-764915c357eb; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=3c3aa0f0-3966-4ba9-b905-1a2365930fba; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=925489ee-37e4-400c-9c29-59cdc99196cc; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=236b7b18-6994-4748-8f19-a4aed1a5f1db; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=3dda8146-05e3-4623-aa8c-da935e9dbd3f; patch: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=a5aae843-34b2-4f65-ba54-89f09509c737; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=829425fd-6030-4f2e-aef2-931a9f735554; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=c0f9923f-791b-4e31-875c-d70a3a7d918e\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=892fb4d1-ced5-44d8-a3d6-84a347106ba1; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=09f22061-975e-4395-b8d2-36b3f76ce842; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=da12a1f6-e22f-422f-9f5a-3d3a4b3db8cd; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=42f39dec-a502-4d50-996e-66e9be87fed4; patch: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=3dda8146-05e3-4623-aa8c-da935e9dbd3f; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=925489ee-37e4-400c-9c29-59cdc99196cc\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=d0f49dfa-20b7-494c-85c3-74bcebce6c2f; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=6fe4ff60-6861-462a-a11f-d760fa62ab83; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=c033925c-9d09-4bb1-90da-151d16102e85; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=79b16023-c50e-41d0-8fea-e14dcf5cfafa; patch: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=09f22061-975e-4395-b8d2-36b3f76ce842; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=42f39dec-a502-4d50-996e-66e9be87fed4\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=8de99aa7-abfd-4a9f-a784-966679d1f39b; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=790c1454-5451-4476-bab1-9c77fde6a81f; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=065bb675-0ef2-431f-9d33-84cd1bb4935d; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=7933b5ab-f8c9-42b9-8479-f78eceb43224; patch: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=6fe4ff60-6861-462a-a11f-d760fa62ab83; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=79b16023-c50e-41d0-8fea-e14dcf5cfafa; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=3c3aa0f0-3966-4ba9-b905-1a2365930fba\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=6482b408-5756-4fe7-baec-a256190f9af7; patch: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=7933b5ab-f8c9-42b9-8479-f78eceb43224\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=eb52c44f-1691-4146-8e69-9711de958cea; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=53b06b0d-dcf7-475b-b6e5-d1930c3cfc52; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=546e246a-66e2-43a5-8181-2678acb61d54; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=248d2e53-c72c-40f0-949c-c5213bb9c3d7; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=8daab8cf-42aa-43e6-8bde-62c60162ccc4; patch: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=065bb675-0ef2-431f-9d33-84cd1bb4935d; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=6482b408-5756-4fe7-baec-a256190f9af7\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=308241ef-550e-4f19-bb73-c2a9e6e36371; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=f2c7aa53-940b-48da-aa63-66944e6a6546; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=c2c6c9d7-5209-41b8-8ed7-c488acaa7d2d; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=b9dd967c-f23e-4f28-82c6-e9b280c656db; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=16957e58-4828-4760-8617-0a1918144467; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=8803740c-a15c-4106-a44c-2aace2b47b13\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "patch: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=8daab8cf-42aa-43e6-8bde-62c60162ccc4\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=896492a1-99bf-4c4a-a65f-25ce2c28b97e; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=2e836817-4ee7-41f2-9bc4-74735d817872; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=bb2ea30d-0240-47ef-a6d8-2598bd4c5709; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=204239d8-f4ea-4190-ad97-1d907465d888; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=1e38b790-68ce-4424-82f2-26255f21c92b; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=cbb331c8-2396-4c46-a849-6c338226f518; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=7a4fcbcf-646e-4e7b-b3f6-ea0ab21ee0ab; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=7eb5634e-3ea6-4c92-8490-1b4879122c08; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=8682e1c6-9af5-40da-a206-4653ccb8d239; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=8de88615-e0b9-423b-9b4f-1bda7afacfa2; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=769adfd8-cb22-469e-aa4a-7d4e81bc08a9; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=935cab7e-464e-428c-a134-f262c1805fcd; patch: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=546e246a-66e2-43a5-8181-2678acb61d54; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=53b06b0d-dcf7-475b-b6e5-d1930c3cfc52; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=b9dd967c-f23e-4f28-82c6-e9b280c656db; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=8803740c-a15c-4106-a44c-2aace2b47b13; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=c2c6c9d7-5209-41b8-8ed7-c488acaa7d2d\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "patch: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=1e38b790-68ce-4424-82f2-26255f21c92b\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=b34909a7-a575-44cf-89dd-d8fee68f0d8a; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=95e97bc6-9076-4107-aff4-06ca1255e6a3; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=bd1e986a-b723-4ed6-bd49-aeacc994fd85; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=3a935932-9bfe-432a-a96c-07aa27272bf9; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=b5e2a72f-4b67-4e33-a6ba-359320db9473; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=2031547a-490f-4751-829a-ef98a23bb023; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=f0c219e2-e5a4-4beb-84f5-85c393914831; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=b36b252f-1f19-4ccd-aa8d-5cd4a98a5112; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=b73c426d-e259-4249-9058-83de3aa73580; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=9e992bbe-63f5-4a35-afd1-e7e5f30ed0fe; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=d095fff9-919e-47c6-a095-15da390156f6; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=0194d7e5-403d-40ac-86ee-b61538d5dcc2; patch: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=bb2ea30d-0240-47ef-a6d8-2598bd4c5709; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=2e836817-4ee7-41f2-9bc4-74735d817872\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=c9750ca1-6135-44c6-b335-eff6ba8cfafa; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=3a5a5526-a619-4505-a578-3ee291080783; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=2836a100-e2e6-40cf-881a-691c470c6092; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=b9ebb6ca-9591-413b-92b2-191f4b0e8cd2; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=58b24ce1-7ff6-40ca-ba6e-cf864fa04a9c; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=10017df8-ecf8-4bda-8c5f-e9a9701a5514; patch: trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=935cab7e-464e-428c-a134-f262c1805fcd; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=8de88615-e0b9-423b-9b4f-1bda7afacfa2; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=8682e1c6-9af5-40da-a206-4653ccb8d239\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=74ce6e89-f717-4846-b7a3-a9e32186d041; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=996f55c7-6763-4e92-b5a9-6758d57218e4; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=a4611617-53da-4a93-a1fc-16c76e3ac7d5; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=c8b9d3a0-5e87-4991-810a-59f9d447ffab; patch: trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=b9ebb6ca-9591-413b-92b2-191f4b0e8cd2; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=10017df8-ecf8-4bda-8c5f-e9a9701a5514; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=2836a100-e2e6-40cf-881a-691c470c6092; trace=308241ef-550e-4f19-bb73-c2a9e6e36371,id=308241ef-550e-4f19-bb73-c2a9e6e36371\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=4bfe17a4-c2d7-4b7f-9f81-814ea2e94fa7; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=4eed6d6e-6b18-4605-aa73-0512b6d13408; patch: trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=0194d7e5-403d-40ac-86ee-b61538d5dcc2; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=b5e2a72f-4b67-4e33-a6ba-359320db9473; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=3a935932-9bfe-432a-a96c-07aa27272bf9; trace=e8a28082-0011-4e85-a399-9bf6bebd6014,id=e8a28082-0011-4e85-a399-9bf6bebd6014\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=46398dce-c38f-4b57-9ab8-b70b30ec0711; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=d2212d1f-3b2a-4733-af7b-6194bae1f8a5; patch: trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=1575bbfe-f738-4a87-8df8-c57e55435560; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=b6f642f0-0cfb-450c-9d96-8a0079d220cf; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=b0830d8e-fdc7-470a-87d7-f70485289152; trace=2f60f3cb-8969-43c1-9be6-a38da876bbeb,id=2f60f3cb-8969-43c1-9be6-a38da876bbeb\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=f1c330b0-3a72-4fe3-93cf-eb25a66445c0; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=6bfb3608-19d8-469d-9e47-206d72f61bed; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=ee5ed22d-8e5b-496e-8478-2d11506f5b1a; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=c4d5b203-a217-4640-ae9d-417e37a10447; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=15f7947e-48e2-4a1f-ba21-31448bb3f17d; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=2b4b590f-943d-4495-ae0b-212af05bee7f\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=300beffa-9bd9-4084-96cd-a2ad42a2ec6f; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=5c424b33-bda2-4f07-a050-d06943845061; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=574cb640-ed02-4b4d-9b9b-f4ff602292fa; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=00826e0e-7ddd-411a-bfbb-326a438bf771; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=f711bbcf-a1ed-4087-a0bf-59b32580127d; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=f477ef0b-11b4-4a28-bb09-ecb45b31870f; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=34d3b6b4-2145-49bd-a718-8b7098875cd9; patch: trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=2b4b590f-943d-4495-ae0b-212af05bee7f; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=c4d5b203-a217-4640-ae9d-417e37a10447; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=ee5ed22d-8e5b-496e-8478-2d11506f5b1a\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=f12b21d7-7f82-4f9c-bee2-e7ea8398fe8e; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=90f2d256-cbeb-48af-b063-ee672167e505; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=221ba585-94c5-46ba-8c84-ce984b2ebd33; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=d9ba91e2-912f-4e47-9420-bb36b7d1cfc7; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=5e591b84-3227-46b3-9601-ddbc814a7ee8; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=7cf59b4f-afe1-4f54-8bb7-d44a7e3ce641; patch: trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=34d3b6b4-2145-49bd-a718-8b7098875cd9; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=f711bbcf-a1ed-4087-a0bf-59b32580127d; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=00826e0e-7ddd-411a-bfbb-326a438bf771\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=6d4f6338-5d7a-4e6b-b912-28fea3a7fd56; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=d895936e-62eb-435b-939c-7f1be7bde063; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=8748fc16-2544-4513-80ef-c80785a8e68b; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=138a1ded-f2dc-491b-9b37-ec4c0f069d6e; patch: trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=d9ba91e2-912f-4e47-9420-bb36b7d1cfc7; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=7cf59b4f-afe1-4f54-8bb7-d44a7e3ce641; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=221ba585-94c5-46ba-8c84-ce984b2ebd33\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "patch: trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=138a1ded-f2dc-491b-9b37-ec4c0f069d6e; trace=f1c330b0-3a72-4fe3-93cf-eb25a66445c0,id=f1c330b0-3a72-4fe3-93cf-eb25a66445c0\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=491f3e66-6b89-4377-8d2b-0567324aa59b; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=b2c086da-93db-4650-9eb2-ed5c40933900; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=ce04256f-5a48-49bc-b35b-705cb40fed33; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=cf90dc89-a96a-442d-b5d4-8bf7781f06d2; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=ae59a011-e2c9-4d4b-82a4-ac9b79440208; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=f8a804e2-c4fa-492c-96bb-78ff7424cf28\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=a7b13e32-9118-409e-8681-20b7b67d3685; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=6f26aba5-5f17-4d71-8578-af3d2a7888e2; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=62a5af0d-8be9-4fb6-9c78-e16654d0bcdc; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=415a3f17-ac3c-42cd-9b4e-5fe90e077649; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=d8ae0cef-b38d-46db-9b75-7d0f08bb3f8d; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=e9c511c0-d35b-4d92-b2d1-cb8ccfb0765b; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=65785df3-40bd-4c31-ad0b-00fa4dec7294; patch: trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=cf90dc89-a96a-442d-b5d4-8bf7781f06d2; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=f8a804e2-c4fa-492c-96bb-78ff7424cf28; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=ce04256f-5a48-49bc-b35b-705cb40fed33\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=20f771b7-e32a-42d6-abc9-c519d6bcdc72; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=805436bf-32ef-4c27-9e1a-eb34f8f34f70; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=a2e50c51-d9ad-4a40-bcd6-0672fa7999fe; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=cdda352a-c4e3-426d-82f9-405de1196d78; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=e3bf8d3e-4ae2-466e-8566-d95a8658757c; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=9cbe96b9-7601-4c50-b04f-8f2573cdd73b; patch: trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=65785df3-40bd-4c31-ad0b-00fa4dec7294; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=d8ae0cef-b38d-46db-9b75-7d0f08bb3f8d; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=415a3f17-ac3c-42cd-9b4e-5fe90e077649\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=137ad066-c15a-4d60-abf7-e831cedb7ad7; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=502fe608-5374-46cf-bfda-ff8f5d2b0297; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=e39c89c2-72c0-4ddc-8ce3-d20b9c3fa9b5; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=3ff9d270-d6a0-422c-b9e6-0a75f916192d; patch: trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=cdda352a-c4e3-426d-82f9-405de1196d78; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=9cbe96b9-7601-4c50-b04f-8f2573cdd73b; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=a2e50c51-d9ad-4a40-bcd6-0672fa7999fe; trace=491f3e66-6b89-4377-8d2b-0567324aa59b,id=491f3e66-6b89-4377-8d2b-0567324aa59b\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=e2edb52e-5cf3-404b-b3ae-f8830317fda0; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=014f95c4-8fa5-481c-a664-3f459fb1f058; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=61be8c64-2bee-43a2-a107-305d4950e1c4; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=3cc13b0d-bd8f-46c8-8362-74d54f98cdb2; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=8b08484a-0e45-424d-9c34-62775c3c5f9f; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=55bc59e8-e5a3-47ba-b4c7-2062ce102680\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=209e52e1-a9b4-4151-a4e3-8e3af16519cc; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=47e036bd-d91b-44b3-8045-5599c1ef67d2; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=ec44fa1a-ce6b-4b06-adbd-1f85768d1e01; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=ddfa373f-f271-49a8-8602-44a7e6f0679e; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=447540dd-c7ab-49e5-b3b6-18f8f99469c6; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=21ac4f51-cd70-4cf9-9049-e5d84a4b5199; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=edf300c5-c07a-4728-a3ac-c4ee52a9ec6d; patch: trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=3cc13b0d-bd8f-46c8-8362-74d54f98cdb2; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=55bc59e8-e5a3-47ba-b4c7-2062ce102680; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=61be8c64-2bee-43a2-a107-305d4950e1c4\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=042fe32d-780d-4518-82e9-1f5d67a094b2; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=36d4d6bf-c37c-4b11-ba2e-5eac1415922e; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=acac7846-6fa0-47c9-9f63-bba4abdadeda; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=5e1dd1b0-f251-4e38-b004-6146ae1d5d5f; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=b6ca0e33-1ad6-4946-9ee5-447c288f2c4f; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=4fcdf5a2-6a73-4ccc-85c6-7883b84cadd6; patch: trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=edf300c5-c07a-4728-a3ac-c4ee52a9ec6d; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=447540dd-c7ab-49e5-b3b6-18f8f99469c6; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=ddfa373f-f271-49a8-8602-44a7e6f0679e\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=1bb46244-06fc-408f-a0ed-e6e16d64519e; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=dfbf1bfb-e3d8-4827-9b3c-13cb32ec2c81; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=750a11db-ae8e-424d-9638-037120e8be71; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=7a9ba21a-78bf-48f3-aa87-773016bccfc7; patch: trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=4fcdf5a2-6a73-4ccc-85c6-7883b84cadd6; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=5e1dd1b0-f251-4e38-b004-6146ae1d5d5f; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=acac7846-6fa0-47c9-9f63-bba4abdadeda; trace=e2edb52e-5cf3-404b-b3ae-f8830317fda0,id=e2edb52e-5cf3-404b-b3ae-f8830317fda0\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=02dab163-549d-452b-95f5-357abc76b1ca; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=b2276546-d946-4ad3-a0e9-1badcbb00b2c; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=ba3fd8fd-db9a-4183-b14d-cfe9b8f89d70; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=658fd17b-6872-4ced-80d8-6ec7a5526ef6; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=b48d32e1-b01e-4b88-91a6-fc1b51755cb0; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=e9e82ab7-bec0-4505-9169-399202079b30\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=b5e1454c-ed29-4593-825f-d2fbbf551f66; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=7fc5c94e-d8e8-4400-a9f8-15e2f599efaf; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=2b9b3d7f-683f-4e47-9cfa-36a30e0f91dd; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=1b8b1051-bf04-4bab-a8d2-7c6317880b6c; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=d496995e-79fb-48ec-81a9-8435de5284be; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=80de6581-7286-4c29-bc9c-2feddeb94bc8; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=c17b7a44-4986-4eba-bcd0-512bcdbbac1a; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=18658beb-1c58-4cc3-9eb7-ba70fe839fab; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=11b7b682-bf75-44aa-940c-28963bdba7b6; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=f2f9b521-b18e-4418-ab71-6b507660bbfa; patch: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=658fd17b-6872-4ced-80d8-6ec7a5526ef6; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=e9e82ab7-bec0-4505-9169-399202079b30; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=ba3fd8fd-db9a-4183-b14d-cfe9b8f89d70\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=ea5fbfa7-b672-4313-b656-f3a2774f83d5; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=fac457d6-9b8d-4a61-9049-2cc3fbb85735; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=e7bd60d0-596e-4d3e-a0bd-0d84f1e50cd1; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=c625ba0b-7a65-4c66-a294-8f85adaf9c76; patch: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=18658beb-1c58-4cc3-9eb7-ba70fe839fab; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=f2f9b521-b18e-4418-ab71-6b507660bbfa\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=ca6df88d-f280-4f24-ac33-f2441c758acc; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=98bf6d3c-bc56-453c-b018-67ea9cdc7e11; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=2c012d2a-bc66-4321-9f8a-7211506e1f25; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=e79d0d5c-4f84-4fde-9ee3-29a46110844a; patch: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=fac457d6-9b8d-4a61-9049-2cc3fbb85735; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=c625ba0b-7a65-4c66-a294-8f85adaf9c76\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=3c381856-3e4d-4815-ae50-ffdc0644639c; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=6e015dc8-be67-4793-a86e-79d568f77ec7; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=94e4fd64-d54d-423f-9c51-c76f3d5fb2b3; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=7144c5ef-7f1c-4d66-b20a-817834923d6d; patch: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=98bf6d3c-bc56-453c-b018-67ea9cdc7e11; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=e79d0d5c-4f84-4fde-9ee3-29a46110844a; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=c17b7a44-4986-4eba-bcd0-512bcdbbac1a\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=c794e961-8cdc-4bfa-adf2-309c9c392d70; patch: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=7144c5ef-7f1c-4d66-b20a-817834923d6d\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=7a5f6504-348d-4ad5-a8f5-4b8b4e90fe84; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=c22f2aae-81ae-4996-80d3-a3b73850b032; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=98fe14eb-c560-42b6-bc14-90956b6fe3a4; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=5e69617c-fd4c-42ba-a589-ac6f145c611e; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=38849e56-fcbb-45a4-96cb-b8fac6efdc0e; patch: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=c794e961-8cdc-4bfa-adf2-309c9c392d70; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=94e4fd64-d54d-423f-9c51-c76f3d5fb2b3\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "patch: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=38849e56-fcbb-45a4-96cb-b8fac6efdc0e\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=ac671d39-be49-46f3-ad7d-215d75551343; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=00f5a628-c403-4924-b172-ca63473a6903; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=1a7ad33d-d834-4908-8cd9-1815c74007b3; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=49d1030f-380b-42e2-9fec-39799575f587; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=58432383-aedc-41e7-8628-7dc0845f757a; patch: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=c22f2aae-81ae-4996-80d3-a3b73850b032; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=98fe14eb-c560-42b6-bc14-90956b6fe3a4\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "patch: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=58432383-aedc-41e7-8628-7dc0845f757a\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=11c13c61-f3d2-4173-a2fa-659e7948207c; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=b755f27a-bdd9-4fc7-9d33-e5c992541f03; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=935ac438-e3ab-42fc-94bb-e3b4664e5092; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=0d25e7fd-8b83-4f66-9db0-59a371a32ed8; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=aac7dbf2-7a37-4ed3-be8a-a54a45838ab2; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=3c20511d-c43b-4639-8797-c63e47b4cd85; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=e70182ba-4089-4c3e-8f57-5e4c310643db; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=892b2c6c-4547-4d3b-99cc-642f20d2974c; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=673edae4-acc1-4b62-ac3d-99b514498feb; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=08f01bef-fb34-462a-9021-fdb6f2ca626a; patch: trace=02dab163-549d-452b-95f5-357abc76b1ca,id=02dab163-549d-452b-95f5-357abc76b1ca; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=00f5a628-c403-4924-b172-ca63473a6903; trace=02dab163-549d-452b-95f5-357abc76b1ca,id=1a7ad33d-d834-4908-8cd9-1815c74007b3\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=da982506-c769-4e99-8a13-3ba28464e33b; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=803d28f6-b6ea-4cf5-a58a-7dda7d6595b3; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=f6ea6f7c-11e0-4ec0-8246-f17c9e3a1530; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=1df00cc2-16fd-405a-a6c9-6b8145c94831; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=b35ca0a2-f164-4eb6-ad9b-28423952d4e4; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=2ef747d6-4c0c-4815-b129-e48e351ad15d\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=bab40355-b53d-4cd9-8ee9-20290527d34e; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=c1990c0d-4619-445a-a520-69512a249b75; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=4ee24498-28c3-44aa-bc41-0172e3a4b1ae; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=9e73082d-b9c3-4c25-84af-70aa7a2f8377; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=4017961e-ad43-4606-be18-af0403b12197; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=e80dd6f0-f708-4b51-8970-938bdaecaa8f; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=b084b76d-4094-4d45-8d14-368d457f32c2; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=0e3b9ea0-127d-44ae-969a-0b6f48c8e4ee; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=ab8439f4-6581-4045-857e-0263dbacb2a7; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=2ac275a0-763a-43ca-b933-c0ecd977fd72; patch: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=1df00cc2-16fd-405a-a6c9-6b8145c94831; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=2ef747d6-4c0c-4815-b129-e48e351ad15d; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=f6ea6f7c-11e0-4ec0-8246-f17c9e3a1530\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=2fb7f717-c9a8-4a43-86c2-d85f36e81abf; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=00b153be-2ee7-44a7-aa9e-ec61c6098a38; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=f42be082-2a10-4fcf-a4e6-bb4c497af1ab; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=67f8b219-494c-46fc-8430-8b9a7a52c2ab; patch: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=0e3b9ea0-127d-44ae-969a-0b6f48c8e4ee; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=2ac275a0-763a-43ca-b933-c0ecd977fd72\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=0905cb29-5bef-4dcc-947e-bd41be9b0ec2; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=c4801355-a8c1-4df3-89c0-b44d205f3790; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=e154c1c3-b46d-484b-863e-9eca46ffe0ef; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=4b49816d-34bf-4999-aa9f-f2d87b8e2c5c; patch: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=00b153be-2ee7-44a7-aa9e-ec61c6098a38; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=67f8b219-494c-46fc-8430-8b9a7a52c2ab\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=dc4cdcc8-b4f8-483e-b5ad-a48a0822ebc9; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=903f59e9-15b7-4011-935c-3f722b2c14a8; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=97d142ef-f894-4d7c-873a-58a068ffd16c; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=3686b997-8404-4be7-9ce4-4c1555e5c444; patch: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=c4801355-a8c1-4df3-89c0-b44d205f3790; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=4b49816d-34bf-4999-aa9f-f2d87b8e2c5c; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=b084b76d-4094-4d45-8d14-368d457f32c2\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=db8cd743-d6dd-4cfc-b5b4-6b8020e34c8f; patch: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=3686b997-8404-4be7-9ce4-4c1555e5c444\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=1fb6b541-86e8-49d3-a76c-27f51ee91700; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=d5e21461-3554-4392-ba75-1d711b79a62a; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=d0459516-1ced-4de1-9356-7cbc7d4baaec; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=c9639f80-afb8-48f8-8d9a-1b501401d6f9; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=98d54136-8f2a-4209-b67d-7ac9b02cb0a9; patch: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=97d142ef-f894-4d7c-873a-58a068ffd16c; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=db8cd743-d6dd-4cfc-b5b4-6b8020e34c8f\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "patch: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=98d54136-8f2a-4209-b67d-7ac9b02cb0a9\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=f28cfa46-8364-45d0-9714-1a2ad3254cb1; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=bd0eabc6-a234-4592-86be-8f9f5c8b855b; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=0bff4eec-387f-484d-8a27-e739d25c3df6; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=6b24c078-4a9b-4e5e-959b-6453d7c95659; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=5b0b1565-7505-4f13-a2ff-92b1260b67cf; patch: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=d5e21461-3554-4392-ba75-1d711b79a62a; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=d0459516-1ced-4de1-9356-7cbc7d4baaec\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "patch: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=5b0b1565-7505-4f13-a2ff-92b1260b67cf\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=dad8a97a-01d7-42c2-b511-e07843681bf1; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=0b20f8a9-eb2e-4874-adbe-821b0d472974; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=a4f0328f-3347-4e88-83c3-db81240d21e8; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=9cfce8f4-12fc-4dfb-902e-f8ebe1f76d5f; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=61373688-556e-4e19-b5be-97b5ce3d6232; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=cc47f4f3-286c-4b88-8692-4345c63abad8; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=b2035953-5c25-4bea-b4ad-57d249c7d1dd; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=daab100c-dcf2-47c5-bf5c-bbfa11184c48; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=090231d4-2f0d-47b8-91ec-204a2899e2b8; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=4fa94396-fe15-47a2-a393-b4d01e579c4b; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=7af40ed7-5329-4432-a158-9daafa6e3768; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=c7a9c907-315b-488b-a03a-b9164cc392e4; patch: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=bd0eabc6-a234-4592-86be-8f9f5c8b855b; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=0bff4eec-387f-484d-8a27-e739d25c3df6\n", "WARNING:langsmith.client:Failed to batch ingest runs: langsmith.utils.LangSmithAuthError: Authentication failed for https://api.smith.langchain.com/runs/batch. HTTPError('401 Client Error: Unauthorized for url: https://api.smith.langchain.com/runs/batch', '{\"detail\":\"Using legacy API key. Please generate a new API key.\"}')\n", "post: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=e9b1009a-8388-41e5-9f5d-b23e5d7a0135; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=5d2f00d2-b8f3-423e-b7b5-b6751cd18ee2; patch: trace=da982506-c769-4e99-8a13-3ba28464e33b,id=c7a9c907-315b-488b-a03a-b9164cc392e4; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=61373688-556e-4e19-b5be-97b5ce3d6232; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=9cfce8f4-12fc-4dfb-902e-f8ebe1f76d5f; trace=da982506-c769-4e99-8a13-3ba28464e33b,id=da982506-c769-4e99-8a13-3ba28464e33b\n" ] } ], "source": [ "retriever.invoke(\"hydrogen import evolutions\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.2 Retriever node" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "import sys\n", "import os\n", "from contextlib import contextmanager\n", "\n", "from climateqa.engine.reranker import rerank_docs\n", "\n", "\n", "\n", "def divide_into_parts(target, parts):\n", " # Base value for each part\n", " base = target // parts\n", " # Remainder to distribute\n", " remainder = target % parts\n", " # List to hold the result\n", " result = []\n", " \n", " for i in range(parts):\n", " if i < remainder:\n", " # These parts get base value + 1\n", " result.append(base + 1)\n", " else:\n", " # The rest get the base value\n", " result.append(base)\n", " \n", " return result\n", "\n", "\n", "@contextmanager\n", "def suppress_output():\n", " # Open a null device\n", " with open(os.devnull, 'w') as devnull:\n", " # Store the original stdout and stderr\n", " old_stdout = sys.stdout\n", " old_stderr = sys.stderr\n", " # Redirect stdout and stderr to the null device\n", " sys.stdout = devnull\n", " sys.stderr = devnull\n", " try:\n", " yield\n", " finally:\n", " # Restore stdout and stderr\n", " sys.stdout = old_stdout\n", " sys.stderr = old_stderr\n", "\n", "\n", "def make_graph_retriever_node(vectorstore, reranker, rerank_by_question=True, k_final=15, k_before_reranking=100):\n", "\n", " def retrieve_graphs(state):\n", " print(\"---- Retrieving graphs ----\")\n", " \n", " POSSIBLE_SOURCES = [\"IEA\", \"OWID\"]\n", " questions = state[\"questions\"]\n", " sources_input = state[\"sources_input\"]\n", "\n", " auto_mode = \"auto\" in sources_input\n", "\n", " # There are several options to get the final top k\n", " # Option 1 - Get 100 documents by question and rerank by question\n", " # Option 2 - Get 100/n documents by question and rerank the total\n", " if rerank_by_question:\n", " k_by_question = divide_into_parts(k_final,len(questions))\n", " \n", " docs = []\n", " \n", " for i,q in enumerate(questions):\n", " \n", " question = q[\"question\"]\n", " \n", " print(f\"Subquestion {i}: {question}\")\n", " \n", " # If auto mode, we use all sources\n", " if auto_mode:\n", " sources = POSSIBLE_SOURCES\n", " # Otherwise, we use the config\n", " else:\n", " sources = sources_input\n", "\n", " if any([x in POSSIBLE_SOURCES for x in sources]):\n", "\n", " sources = [x for x in sources if x in POSSIBLE_SOURCES]\n", " \n", " # Search the document store using the retriever\n", " retriever = GraphRetriever(\n", " vectorstore = vectorstore,\n", " sources = sources,\n", " k_total = k_before_reranking,\n", " threshold = 0.5,\n", " )\n", " docs_question = retriever.get_relevant_documents(question)\n", " \n", " # Rerank\n", " if reranker is not None:\n", " with suppress_output():\n", " docs_question = rerank_docs(reranker,docs_question,question)\n", " else:\n", " # Add a default reranking score\n", " for doc in docs_question:\n", " doc.metadata[\"reranking_score\"] = doc.metadata[\"similarity_score\"]\n", " \n", " # If rerank by question we select the top documents for each question\n", " if rerank_by_question:\n", " docs_question = docs_question[:k_by_question[i]]\n", " \n", " # Add sources used in the metadata\n", " for doc in docs_question:\n", " doc.metadata[\"sources_used\"] = sources\n", " \n", " print(f\"{len(docs_question)} graphs retrieved for subquestion {i + 1}: {docs_question}\")\n", " \n", " # Add to the list of docs\n", " docs.extend(docs_question)\n", "\n", " else:\n", " print(f\"There are no graphs which match the sources filtered on. Sources filtered on: {sources}. Sources available: {POSSIBLE_SOURCES}.\")\n", " \n", " # Sorting the list in descending order by rerank_score\n", " # Then select the top k\n", " docs = sorted(docs, key=lambda x: x.metadata[\"reranking_score\"], reverse=True)\n", " docs = docs[:k_final]\n", "\n", " return {\"recommended_content\": docs}\n", " \n", " return retrieve_graphs" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "# import sys\n", "# import os\n", "# from contextlib import contextmanager\n", "\n", "# from climateqa.engine.reranker import rerank_docs\n", "\n", "\n", "# def divide_into_parts(target, parts):\n", "# # Base value for each part\n", "# base = target // parts\n", "# # Remainder to distribute\n", "# remainder = target % parts\n", "# # List to hold the result\n", "# result = []\n", " \n", "# for i in range(parts):\n", "# if i < remainder:\n", "# # These parts get base value + 1\n", "# result.append(base + 1)\n", "# else:\n", "# # The rest get the base value\n", "# result.append(base)\n", " \n", "# return result\n", "\n", "\n", "# @contextmanager\n", "# def suppress_output():\n", "# # Open a null device\n", "# with open(os.devnull, 'w') as devnull:\n", "# # Store the original stdout and stderr\n", "# old_stdout = sys.stdout\n", "# old_stderr = sys.stderr\n", "# # Redirect stdout and stderr to the null device\n", "# sys.stdout = devnull\n", "# sys.stderr = devnull\n", "# try:\n", "# yield\n", "# finally:\n", "# # Restore stdout and stderr\n", "# sys.stdout = old_stdout\n", "# sys.stderr = old_stderr\n", "\n", "\n", "\n", "# def make_retriever_node(vectorstore, reranker, rerank_by_question=True, k_final=15, k_before_reranking=100):\n", "\n", "# def retrieve_documents(state):\n", " \n", "# POSSIBLE_SOURCES = [\"IEA\",\"OWID\"]\n", "# questions = state[\"questions\"]\n", "# sources_input = state[\"sources_input\"]\n", " \n", "# # Sert à rien pour l'instant puisqu'on a des valeurs par défaut et qu'on fait pas de query transformation sur les sources de graphs\n", "# # Use sources from the user input or from the LLM detection\n", "# if \"sources_input\" not in state or state[\"sources_input\"] is None:\n", "# sources_input = [\"auto\"]\n", "# else:\n", "# sources_input = state[\"sources_input\"]\n", "# auto_mode = \"auto\" in sources_input\n", "\n", "# # There are several options to get the final top k\n", "# # Option 1 - Get 100 documents by question and rerank by question\n", "# # Option 2 - Get 100/n documents by question and rerank the total\n", "# if rerank_by_question:\n", "# k_by_question = divide_into_parts(k_final,len(questions))\n", " \n", "# docs = []\n", " \n", "# for i,q in enumerate(questions):\n", " \n", "# sources = q[\"sources\"]\n", "# question = q[\"question\"]\n", " \n", "# # If auto mode, we use the sources detected by the LLM\n", "# if auto_mode:\n", "# sources = [x for x in sources if x in POSSIBLE_SOURCES]\n", " \n", "# # Otherwise, we use the config\n", "# else:\n", "# sources = sources_input\n", " \n", "# # Search the document store using the retriever\n", "# # Configure high top k for further reranking step\n", "# retriever = GraphRetriever(\n", "# vectorstore=vectorstore,\n", "# sources = sources,\n", "# k_total = k_before_reranking,\n", "# threshold = 0.5,\n", "# )\n", "# docs_question = retriever.get_relevant_documents(question)\n", " \n", "# # Rerank\n", "# if reranker is not None:\n", "# with suppress_output():\n", "# docs_question = rerank_docs(reranker,docs_question,question)\n", "# else:\n", "# # Add a default reranking score\n", "# for doc in docs_question:\n", "# # doc.metadata[\"reranking_score\"] = doc.metadata[\"similarity_score\"]\n", "# doc.metadata[\"reranking_score\"] = \"No reranking\"\n", " \n", "# # If rerank by question we select the top documents for each question\n", "# if rerank_by_question:\n", "# docs_question = docs_question[:k_by_question[i]]\n", " \n", "# # Add sources used in the metadata\n", "# for doc in docs_question:\n", "# doc.metadata[\"sources_used\"] = sources\n", " \n", "# # Add to the list of docs\n", "# docs.extend(docs_question)\n", " \n", "# # Sorting the list in descending order by rerank_score\n", "# # Then select the top k\n", "# docs = sorted(docs, key=lambda x: x.metadata[\"reranking_score\"], reverse=True)\n", "# docs = docs[:k_final]\n", " \n", "# new_state = {\"documents\": docs}\n", "# return new_state\n", " \n", "# return retrieve_documents" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. Node functions" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "from operator import itemgetter\n", "\n", "from langchain_core.prompts import ChatPromptTemplate\n", "from langchain_core.output_parsers import StrOutputParser\n", "from langchain_core.prompts.prompt import PromptTemplate\n", "from langchain_core.prompts.base import format_document\n", "\n", "DEFAULT_DOCUMENT_PROMPT = PromptTemplate.from_template(template=\"\"\"Title: {page_content}. \\n\\n Embedding link: {returned_content}\"\"\")\n", "\n", "def _combine_recommended_content(\n", " docs, document_prompt=DEFAULT_DOCUMENT_PROMPT, sep=\"\\n\\n-----------------\\n\\n\"\n", "):\n", "\n", " doc_strings = []\n", "\n", " for i,doc in enumerate(docs):\n", " # chunk_type = \"Doc\" if doc.metadata[\"chunk_type\"] == \"text\" else \"Image\"\n", " chunk_type = \"Graph\"\n", " if isinstance(doc,str):\n", " doc_formatted = doc\n", " else:\n", " doc_formatted = format_document(doc, document_prompt)\n", "\n", " doc_string = f\"{chunk_type} {i+1}: \\n\\n\" + doc_formatted\n", " # doc_string = doc_string.replace(\"\\n\",\" \") \n", " doc_strings.append(doc_string)\n", "\n", " return sep.join(doc_strings)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "# display(Markdown(_combine_recommended_content(output[\"recommended_content\"])))" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "from langchain_core.output_parsers import JsonOutputParser\n", "from langchain_core.prompts import PromptTemplate\n", "from langchain_core.pydantic_v1 import BaseModel, Field\n", "from langchain_openai import ChatOpenAI\n", "\n", "from climateqa.engine.chains.prompts import answer_prompt_graph_template\n", "\n", "class RecommendedGraph(BaseModel):\n", " title: str = Field(description=\"Title of the graph\")\n", " embedding: str = Field(description=\"Embedding link of the graph\")\n", "\n", "# class RecommendedGraphs(BaseModel):\n", "# recommended_content: List[RecommendedGraph] = Field(description=\"List of recommended graphs\")\n", "\n", "def make_rag_graph_chain(llm):\n", " parser = JsonOutputParser(pydantic_object=RecommendedGraph)\n", " prompt = PromptTemplate(\n", " template=answer_prompt_graph_template,\n", " input_variables=[\"query\", \"recommended_content\"],\n", " partial_variables={\"format_instructions\": parser.get_format_instructions()},\n", " )\n", "\n", " chain = prompt | llm | parser\n", " return chain\n", "\n", "def make_rag_graph_node(llm):\n", " chain = make_rag_graph_chain(llm)\n", "\n", " def answer_rag_graph(state):\n", " output = chain.invoke(state)\n", " return {\"graph_returned\": output}\n", "\n", " return answer_rag_graph" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5. Graph" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.1 Make graph agent" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "import sys\n", "import os\n", "from contextlib import contextmanager\n", "\n", "from langchain.schema import Document\n", "from langgraph.graph import END, StateGraph\n", "from langchain_core.runnables.graph import MermaidDrawMethod\n", "\n", "from typing_extensions import TypedDict\n", "from typing import List, Dict\n", "\n", "from IPython.display import display, HTML, Image\n", "\n", "from climateqa.engine.chains.answer_chitchat import make_chitchat_node\n", "from climateqa.engine.chains.answer_ai_impact import make_ai_impact_node\n", "from climateqa.engine.chains.query_transformation import make_query_transform_node\n", "from climateqa.engine.chains.translation import make_translation_node\n", "from climateqa.engine.chains.intent_categorization import make_intent_categorization_node\n", "from climateqa.engine.chains.retriever import make_retriever_node\n", "from climateqa.engine.chains.answer_rag import make_rag_node\n", "from climateqa.engine.chains.set_defaults import set_defaults\n", "from climateqa.engine.chains.graph_retriever import make_graph_retriever_node\n", "\n", "\n", "class GraphState(TypedDict):\n", " \"\"\"\n", " Represents the state of our graph.\n", " \"\"\"\n", " user_input : str\n", " language : str\n", " intent : str\n", " query: str\n", " questions : List[dict]\n", " answer: str\n", " audience: str\n", " sources_input: List[str]\n", " documents: List[Document]\n", " recommended_content : List[Document]\n", " graph_returned: Dict[str,str]\n", "\n", "def search(state):\n", " return {}\n", "\n", "def route_intent(state):\n", " intent = state[\"intent\"]\n", " if intent in [\"chitchat\",\"esg\"]:\n", " return \"answer_chitchat\"\n", " elif intent == \"ai_impact\":\n", " return \"answer_ai_impact\"\n", " else:\n", " # Search route\n", " return \"search\"\n", " \n", "def route_translation(state):\n", " if state[\"language\"].lower() == \"english\":\n", " return \"transform_query\"\n", " else:\n", " return \"translate_query\"\n", " \n", "def route_based_on_relevant_docs(state,threshold_docs=0.2):\n", " docs = [x for x in state[\"documents\"] if x.metadata[\"reranking_score\"] > threshold_docs]\n", " if len(docs) > 0:\n", " return \"answer_rag\"\n", " else:\n", " return \"answer_rag_no_docs\"\n", " \n", "\n", "def make_id_dict(values):\n", " return {k:k for k in values}\n", "\n", "def make_graph_agent(llm, vectorstore_ipcc, vectorstore_graphs, reranker, threshold_docs=0.2):\n", " \n", " workflow = StateGraph(GraphState)\n", "\n", " # Define the node functions\n", " categorize_intent = make_intent_categorization_node(llm)\n", " transform_query = make_query_transform_node(llm)\n", " translate_query = make_translation_node(llm)\n", " answer_chitchat = make_chitchat_node(llm)\n", " answer_ai_impact = make_ai_impact_node(llm)\n", " retrieve_documents = make_retriever_node(vectorstore_ipcc, reranker)\n", " retrieve_graphs = make_graph_retriever_node(vectorstore_graphs, reranker)\n", " answer_rag_graph = make_rag_graph_node(llm)\n", " answer_rag = make_rag_node(llm, with_docs=True)\n", " answer_rag_no_docs = make_rag_node(llm, with_docs=False)\n", "\n", " # Define the nodes\n", " workflow.add_node(\"set_defaults\", set_defaults)\n", " workflow.add_node(\"categorize_intent\", categorize_intent)\n", " workflow.add_node(\"search\", search)\n", " workflow.add_node(\"transform_query\", transform_query)\n", " workflow.add_node(\"translate_query\", translate_query)\n", " workflow.add_node(\"answer_chitchat\", answer_chitchat)\n", " workflow.add_node(\"answer_ai_impact\", answer_ai_impact)\n", " workflow.add_node(\"retrieve_graphs\", retrieve_graphs)\n", " workflow.add_node(\"answer_rag_graph\", answer_rag_graph)\n", " workflow.add_node(\"retrieve_documents\", retrieve_documents)\n", " workflow.add_node(\"answer_rag\", answer_rag)\n", " workflow.add_node(\"answer_rag_no_docs\", answer_rag_no_docs)\n", "\n", " # Entry point\n", " workflow.set_entry_point(\"set_defaults\")\n", "\n", " # CONDITIONAL EDGES\n", " workflow.add_conditional_edges(\n", " \"categorize_intent\",\n", " route_intent,\n", " make_id_dict([\"answer_chitchat\",\"answer_ai_impact\",\"search\"])\n", " )\n", "\n", " workflow.add_conditional_edges(\n", " \"search\",\n", " route_translation,\n", " make_id_dict([\"translate_query\",\"transform_query\"])\n", " )\n", "\n", " workflow.add_conditional_edges(\n", " \"retrieve_documents\",\n", " lambda x : route_based_on_relevant_docs(x,threshold_docs=threshold_docs),\n", " make_id_dict([\"answer_rag\",\"answer_rag_no_docs\"])\n", " )\n", "\n", " # Define the edges\n", " workflow.add_edge(\"set_defaults\", \"categorize_intent\")\n", " workflow.add_edge(\"translate_query\", \"transform_query\")\n", " workflow.add_edge(\"transform_query\", \"retrieve_graphs\")\n", " workflow.add_edge(\"retrieve_graphs\", \"answer_rag_graph\")\n", " workflow.add_edge(\"answer_rag_graph\", \"retrieve_documents\")\n", " workflow.add_edge(\"answer_rag\", END)\n", " workflow.add_edge(\"answer_rag_no_docs\", END)\n", " workflow.add_edge(\"answer_chitchat\", END)\n", " workflow.add_edge(\"answer_ai_impact\", END)\n", "\n", " # Compile\n", " app = workflow.compile()\n", " return app\n", "\n", "\n", "\n", "\n", "def display_graph(app):\n", "\n", " display(\n", " Image(\n", " app.get_graph(xray = True).draw_mermaid_png(\n", " draw_method=MermaidDrawMethod.API,\n", " )\n", " )\n", " )" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "---- Translate query ----\n" ] }, { "data": { "image/jpeg": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "app = make_graph_agent(llm=llm, vectorstore_ipcc=vectorstore, vectorstore_graphs=vectorstore_graphs, reranker=reranker)\n", "display_graph(app)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "data": { "text/plain": [ "{'environment': True}" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from climateqa.engine.chains.chitchat_categorization import make_chitchat_intent_categorization_chain\n", "\n", "chain = make_chitchat_intent_categorization_chain(llm)\n", "chain.invoke({\"input\": \"should i eat fish\"})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.2 Testing graph agent" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "---- Translate query ----\n" ] }, { "data": { "image/jpeg": "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", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from climateqa.engine.graph import make_graph_agent, display_graph\n", "\n", "app = make_graph_agent(llm=llm, vectorstore_ipcc=vectorstore, vectorstore_graphs=vectorstore_graphs, reranker=reranker)\n", "display_graph(app)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: GET https://api.gradio.app/gradio-messaging/en \"HTTP/1.1 200 OK\"\n", "/tmp/ipykernel_13585/659967580.py:28: LangChainBetaWarning: This API is in beta and may change in the future.\n", " result = app.astream_events(inputs,version = \"v1\") #{\"callbacks\":[MyCustomAsyncHandler()]})\n" ] }, { "ename": "TypeError", "evalue": "'Metadata' object is not subscriptable", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[32], line 52\u001b[0m\n\u001b[1;32m 50\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m event[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;129;01min\u001b[39;00m steps_display\u001b[38;5;241m.\u001b[39mkeys() \u001b[38;5;129;01mand\u001b[39;00m event[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mevent\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mon_chain_start\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;66;03m#display steps\u001b[39;00m\n\u001b[1;32m 51\u001b[0m event_description,display_output \u001b[38;5;241m=\u001b[39m steps_display[node]\n\u001b[0;32m---> 52\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(history[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmetadata\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;129;01mor\u001b[39;00m \u001b[43mhistory\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmetadata\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtitle\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m \u001b[38;5;241m!=\u001b[39m event_description: \u001b[38;5;66;03m# if a new step begins\u001b[39;00m\n\u001b[1;32m 53\u001b[0m history\u001b[38;5;241m.\u001b[39mappend(ChatMessage(role\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124massistant\u001b[39m\u001b[38;5;124m\"\u001b[39m, content \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m, metadata\u001b[38;5;241m=\u001b[39m{\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtitle\u001b[39m\u001b[38;5;124m'\u001b[39m :event_description}))\n\u001b[1;32m 55\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m event[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtransform_query\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m event[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mevent\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mon_chat_model_stream\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m node \u001b[38;5;129;01min\u001b[39;00m [\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124manswer_rag\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124manswer_search\u001b[39m\u001b[38;5;124m\"\u001b[39m]:\u001b[38;5;66;03m# if streaming answer\u001b[39;00m\n", "\u001b[0;31mTypeError\u001b[0m: 'Metadata' object is not subscriptable" ] }, { "name": "stdout", "output_type": "stream", "text": [ "---- Categorize_message ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "Output intent categorization: {'intent': 'search'}\n", "\n", "---- Transform query ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", "/home/tim/ai4s/climate_qa/climate-question-answering/climateqa/engine/chains/graph_retriever.py:91: LangChainDeprecationWarning: The method `BaseRetriever.get_relevant_documents` was deprecated in langchain-core 0.1.46 and will be removed in 1.0. Use invoke instead.\n", " docs_question = retriever.get_relevant_documents(question)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "---- Retrieving graphs ----\n", "Subquestion 0: What is radiative forcing and how does it affect climate change?\n", "8 graphs retrieved for subquestion 1: [Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_386', 'returned_content': '', 'source': 'OWID', 'subtitle': \"This is shown as a country or region's share of the global mean surface temperature change as a result of its cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change', 'similarity_score': 0.8423357605934143, 'content': 'Global warming: Contributions to the change in global mean surface temperature', 'reranking_score': 0.005384462885558605, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming: Contributions to the change in global mean surface temperature'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_780', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Nationally determined contributions (NDCs) embody efforts by each country to reduce national emissions and adapt to the impacts of climate change. The Paris Agreement requires each of the 193 Parties to prepare, communicate and maintain NDCs outlining what they intend to achieve. NDCs must be updated every five years.', 'url': 'https://ourworldindata.org/grapher/nationally-determined-contributions', 'similarity_score': 0.8526537418365479, 'content': 'Nationally determined contributions to climate change', 'reranking_score': 7.293858652701601e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Nationally determined contributions to climate change'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_342', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Emissions factors quantify the average CO₂ output per unit of energy. They are measured in kilograms of CO₂ per megawatt-hour (MWh) of energy from various fossil fuel sources.', 'url': 'https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor', 'similarity_score': 0.8662314414978027, 'content': 'Carbon dioxide emissions factors', 'reranking_score': 6.450313958339393e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Carbon dioxide emissions factors'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_358', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contribution-to-temp-rise-by-gas', 'similarity_score': 0.8814464807510376, 'content': 'Contribution to global mean surface temperature rise by gas', 'reranking_score': 2.3544196665170603e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Contribution to global mean surface temperature rise by gas'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_357', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contribution-temp-rise-degrees', 'similarity_score': 0.8828883171081543, 'content': 'Contribution to global mean surface temperature rise', 'reranking_score': 1.724368667055387e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Contribution to global mean surface temperature rise'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_383', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.', 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source', 'similarity_score': 0.8840625286102295, 'content': 'Global warming contributions by gas and source', 'reranking_score': 1.6588734069955535e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming contributions by gas and source'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_767', 'returned_content': '', 'source': 'OWID', 'subtitle': 'This is measured at a nominal depth of 20cm, and given relative to the average temperature from the period of 1961 - 1990. Measured in degrees Celsius.', 'url': 'https://ourworldindata.org/grapher/sea-surface-temperature', 'similarity_score': 0.9009610414505005, 'content': 'Global warming: monthly sea surface temperature anomaly', 'reranking_score': 1.570666063344106e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming: monthly sea surface temperature anomaly'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_768', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The deviation of a specific year's average surface temperature from the 1991-2020 mean, in degrees Celsius.\", 'url': 'https://ourworldindata.org/grapher/global-yearly-surface-temperature-anomalies', 'similarity_score': 0.9119041562080383, 'content': 'Global yearly surface temperature anomalies', 'reranking_score': 1.5241118489939254e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Global yearly surface temperature anomalies')]\n", "Subquestion 1: What are the different types of radiative forcing and their impacts on the environment?\n", "7 graphs retrieved for subquestion 2: [Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_342', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Emissions factors quantify the average CO₂ output per unit of energy. They are measured in kilograms of CO₂ per megawatt-hour (MWh) of energy from various fossil fuel sources.', 'url': 'https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor', 'similarity_score': 0.8055480122566223, 'content': 'Carbon dioxide emissions factors', 'reranking_score': 2.3946791770868003e-05, 'query_used_for_retrieval': 'What are the different types of radiative forcing and their impacts on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Carbon dioxide emissions factors'), Document(metadata={'category': 'Natural Disasters', 'doc_id': 'owid_1760', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The annual reported number of natural disasters, categorised by type. The number of global reported natural disaster events in any given year. Note that this largely reflects increases in data reporting, and should not be used to assess the total number of events.', 'url': 'https://ourworldindata.org/grapher/natural-disasters-by-type', 'similarity_score': 0.8462469577789307, 'content': 'Global reported natural disasters by type', 'reranking_score': 1.6791396774351597e-05, 'query_used_for_retrieval': 'What are the different types of radiative forcing and their impacts on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Global reported natural disasters by type'), Document(metadata={'category': 'Ozone Layer', 'doc_id': 'owid_1844', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Annual consumption of ozone-depleting substances. Emissions of each gas are given in ODP tonnes, which accounts for the quantity of gas emitted and how \"strong\" it is in terms of depleting ozone.', 'url': 'https://ourworldindata.org/grapher/ozone-depleting-substance-consumption', 'similarity_score': 0.8488471508026123, 'content': 'Emissions of ozone-depleting substances', 'reranking_score': 1.35105183289852e-05, 'query_used_for_retrieval': 'What are the different types of radiative forcing and their impacts on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Emissions of ozone-depleting substances'), Document(metadata={'category': 'Ozone Layer', 'doc_id': 'owid_1847', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Ozone-depleting substance emissions are measured in ODP tonnes.', 'url': 'https://ourworldindata.org/grapher/ozone-depleting-substance-emissions', 'similarity_score': 0.8520827293395996, 'content': 'Ozone-depleting substance emissions', 'reranking_score': 1.2769949535140768e-05, 'query_used_for_retrieval': 'What are the different types of radiative forcing and their impacts on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Ozone-depleting substance emissions'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_383', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.', 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source', 'similarity_score': 0.8670639395713806, 'content': 'Global warming contributions by gas and source', 'reranking_score': 1.2466728549043182e-05, 'query_used_for_retrieval': 'What are the different types of radiative forcing and their impacts on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming contributions by gas and source'), Document(metadata={'category': 'Air Pollution', 'doc_id': 'owid_138', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Annual emissions of particulate matter from all human-induced sources. This is measured in terms of PM₁₀ and PM₂.₅, which denotes particulate matter less than 10 and 2.5 microns in diameter, respectively.', 'url': 'https://ourworldindata.org/grapher/emissions-of-particulate-matter', 'similarity_score': 0.8681329488754272, 'content': 'Emissions of particulate matter', 'reranking_score': 1.2325931493251119e-05, 'query_used_for_retrieval': 'What are the different types of radiative forcing and their impacts on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Emissions of particulate matter'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_387', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Greenhouse gas emissions include carbon dioxide, methane and nitrous oxide from all sources, including land-use change. They are measured in tonnes of carbon dioxide-equivalents over a 100-year timescale.', 'url': 'https://ourworldindata.org/grapher/total-ghg-emissions', 'similarity_score': 0.8768877983093262, 'content': 'Greenhouse gas emissions', 'reranking_score': 1.1929207175853662e-05, 'query_used_for_retrieval': 'What are the different types of radiative forcing and their impacts on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Greenhouse gas emissions')]\n", "---- Retrieve documents ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:langchain_core.callbacks.manager:Error in LogStreamCallbackHandler.on_chain_start callback: ValidationError(model='Run', errors=[{'loc': ('__root__',), 'msg': \"argument of type 'NoneType' is not iterable\", 'type': 'type_error'}])\n", "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_start callback: ValidationError(model='Run', errors=[{'loc': ('__root__',), 'msg': \"argument of type 'NoneType' is not iterable\", 'type': 'type_error'}])\n", "WARNING:langchain_core.callbacks.manager:Error in LogStreamCallbackHandler.on_chain_end callback: TracerException('No indexed run ID d589b647-b2b8-4479-8654-0237320b13e7.')\n", "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_end callback: TracerException('No indexed run ID d589b647-b2b8-4479-8654-0237320b13e7.')\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "---- Retrieve documents ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:langchain_core.callbacks.manager:Error in LogStreamCallbackHandler.on_chain_start callback: ValidationError(model='Run', errors=[{'loc': ('__root__',), 'msg': \"argument of type 'NoneType' is not iterable\", 'type': 'type_error'}])\n", "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_start callback: ValidationError(model='Run', errors=[{'loc': ('__root__',), 'msg': \"argument of type 'NoneType' is not iterable\", 'type': 'type_error'}])\n", "WARNING:langchain_core.callbacks.manager:Error in LogStreamCallbackHandler.on_chain_end callback: TracerException('No indexed run ID 3025729a-c358-4d18-b4eb-7564073fbde4.')\n", "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_end callback: TracerException('No indexed run ID 3025729a-c358-4d18-b4eb-7564073fbde4.')\n", "WARNING:langchain_core.callbacks.manager:Error in LogStreamCallbackHandler.on_chain_start callback: ValidationError(model='Run', errors=[{'loc': ('__root__',), 'msg': \"argument of type 'NoneType' is not iterable\", 'type': 'type_error'}])\n", "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_start callback: ValidationError(model='Run', errors=[{'loc': ('__root__',), 'msg': \"argument of type 'NoneType' is not iterable\", 'type': 'type_error'}])\n", "WARNING:langchain_core.callbacks.manager:Error in LogStreamCallbackHandler.on_chain_end callback: TracerException('No indexed run ID 16e0d163-397b-44a4-b854-0962de03abe9.')\n", "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_end callback: TracerException('No indexed run ID 16e0d163-397b-44a4-b854-0962de03abe9.')\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "---- Answer RAG ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "Answer:\n", "Radiative forcing is a key concept in understanding how human activities affect the Earth's climate. It refers to the change in energy balance in the Earth's atmosphere due to various factors, primarily greenhouse gases (GHGs) and aerosols. Here’s a breakdown of its impact:\n", "\n", "### What is Radiative Forcing?\n", "- **Definition**: Radiative forcing measures how much energy is added to or taken away from the Earth's atmosphere. Positive radiative forcing leads to warming, while negative radiative forcing can cause cooling.\n", "- **Current Status**: As of 2019, human-caused radiative forcing was estimated at 2.72 watts per square meter (W/m²) compared to pre-industrial levels (1750). This represents a significant increase, primarily due to higher concentrations of greenhouse gases like carbon dioxide (CO2) [Doc 1, Doc 9].\n", "\n", "### How Does It Affect the Climate?\n", "- **Energy Accumulation**: The increase in radiative forcing results in more energy being trapped in the climate system, leading to an overall warming effect. The average rate of heating has risen from 0.50 W/m² (1971-2006) to 0.79 W/m² (2006-2018) [Doc 2].\n", "- **Ocean Warming**: A large portion (91%) of this energy accumulation is absorbed by the oceans, which leads to rising sea temperatures. Other areas affected include land warming, ice loss, and atmospheric warming [Doc 2].\n", "\n", "### Contributions to Climate Change\n", "- **Greenhouse Gases**: The primary driver of positive radiative forcing is the increase in greenhouse gases, which trap heat in the atmosphere. Since 2011, the contribution from GHGs has increased by 0.34 W/m² [Doc 1].\n", "- **Aerosols**: While aerosols can have a cooling effect by reflecting sunlight, their overall impact is less than that of greenhouse gases. Changes in aerosol concentrations and their effects on climate are also being better understood [Doc 1, Doc 4].\n", "\n", "### Future Implications\n", "- **Temperature Projections**: The cumulative emissions of CO2 and other greenhouse gases will determine the likelihood of limiting global warming to critical thresholds, such as 1.5°C above pre-industrial levels [Doc 3, Doc 12].\n", "- **Policy and Action**: Understanding radiative forcing is crucial for developing effective climate policies aimed at reducing emissions and mitigating climate change impacts.\n", "\n", "In summary, radiative forcing is a fundamental concept that helps explain how human activities, particularly the release of greenhouse gases, are warming our planet. The ongoing changes in our climate system highlight the urgent need for action to reduce emissions and limit future warming.\n" ] } ], "source": [ "from climateqa.engine.chains.prompts import audience_prompts\n", "from front.utils import make_html_source,parse_output_llm_with_sources,serialize_docs,make_toolbox,generate_html_graphs\n", "from gradio import ChatMessage\n", "init_prompt = \"\"\n", "\n", "docs = []\n", "docs_used = True\n", "docs_html = \"\"\n", "current_graphs = []\n", "output_query = \"\"\n", "output_language = \"\"\n", "output_keywords = \"\"\n", "gallery = []\n", "updates = []\n", "start_streaming = False\n", "\n", "steps_display = {\n", " \"categorize_intent\":(\"🔄️ Analyzing user message\",True),\n", " \"transform_query\":(\"🔄️ Thinking step by step to answer the question\",True),\n", " \"retrieve_documents\":(\"🔄️ Searching in the knowledge base\",False),\n", "}\n", "query = \"what is the impact of radiative forcing\"\n", "inputs = {\"user_input\": query,\"audience\": audience_prompts[\"general\"] ,\"sources\": [\"IPCC\", \"IPBES\", \"IPOS\"]}\n", "history = [ChatMessage(role=\"assistant\", content=init_prompt)]\n", "history + [ChatMessage(role=\"user\", content=query)]\n", "\n", "\n", "result = app.astream_events(inputs,version = \"v1\") #{\"callbacks\":[MyCustomAsyncHandler()]})\n", "\n", "async for event in result:\n", " if \"langgraph_node\" in event[\"metadata\"]:\n", " node = event[\"metadata\"][\"langgraph_node\"]\n", "\n", " if event[\"event\"] == \"on_chain_end\" and event[\"name\"] == \"retrieve_documents\" :# when documents are retrieved\n", " try:\n", " docs = event[\"data\"][\"output\"][\"documents\"]\n", " docs_html = []\n", " for i, d in enumerate(docs, 1):\n", " docs_html.append(make_html_source(d, i))\n", " \n", " used_documents = used_documents + [d.metadata[\"name\"] for d in docs]\n", " history[-1].content = \"Adding sources :\\n\\n - \" + \"\\n - \".join(np.unique(used_documents))\n", " \n", " docs_html = \"\".join(docs_html)\n", " \n", " except Exception as e:\n", " print(f\"Error getting documents: {e}\")\n", " print(event)\n", "\n", " elif event[\"name\"] in steps_display.keys() and event[\"event\"] == \"on_chain_start\": #display steps\n", " event_description,display_output = steps_display[node]\n", " if not hasattr(history[-1], 'metadata') or history[-1].metadata[\"title\"] != event_description: # if a new step begins\n", " history.append(ChatMessage(role=\"assistant\", content = \"\", metadata={'title' :event_description}))\n", "\n", " elif event[\"name\"] != \"transform_query\" and event[\"event\"] == \"on_chat_model_stream\" and node in [\"answer_rag\", \"answer_search\"]:# if streaming answer\n", " if start_streaming == False:\n", " start_streaming = True\n", " history.append(ChatMessage(role=\"assistant\", content = \"\"))\n", " answer_message_content += event[\"data\"][\"chunk\"].content\n", " answer_message_content = parse_output_llm_with_sources(answer_message_content)\n", " history[-1] = ChatMessage(role=\"assistant\", content = answer_message_content)\n", " \n", " elif event[\"name\"] in [\"retrieve_graphs\", \"retrieve_graphs_ai\"] and event[\"event\"] == \"on_chain_end\":\n", " try:\n", " recommended_content = event[\"data\"][\"output\"][\"recommended_content\"]\n", " # graphs = [\n", " # {\n", " # \"embedding\": x.metadata[\"returned_content\"],\n", " # \"metadata\": {\n", " # \"source\": x.metadata[\"source\"],\n", " # \"category\": x.metadata[\"category\"]\n", " # }\n", " # } for x in recommended_content if x.metadata[\"source\"] == \"OWID\"\n", " # ]\n", " \n", " unique_graphs = []\n", " seen_embeddings = set()\n", "\n", " for x in recommended_content:\n", " embedding = x.metadata[\"returned_content\"]\n", " \n", " # Check if the embedding has already been seen\n", " if embedding not in seen_embeddings:\n", " unique_graphs.append({\n", " \"embedding\": embedding,\n", " \"metadata\": {\n", " \"source\": x.metadata[\"source\"],\n", " \"category\": x.metadata[\"category\"]\n", " }\n", " })\n", " # Add the embedding to the seen set\n", " seen_embeddings.add(embedding)\n", "\n", "\n", " categories = {}\n", " for graph in unique_graphs:\n", " category = graph['metadata']['category']\n", " if category not in categories:\n", " categories[category] = []\n", " categories[category].append(graph['embedding'])\n", "\n", " # graphs_html = \"\"\n", " for category, embeddings in categories.items():\n", " # graphs_html += f\"

{category}

\"\n", " # current_graphs.append(f\"

{category}

\")\n", " for embedding in embeddings:\n", " current_graphs.append([embedding, category])\n", " # graphs_html += f\"
{embedding}
\"\n", " \n", " except Exception as e:\n", " print(f\"Error getting graphs: {e}\")" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'Metadata' object is not subscriptable", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[33], line 49\u001b[0m\n\u001b[1;32m 47\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m event[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;129;01min\u001b[39;00m steps_display\u001b[38;5;241m.\u001b[39mkeys() \u001b[38;5;129;01mand\u001b[39;00m event[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mevent\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mon_chain_start\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;66;03m#display steps\u001b[39;00m\n\u001b[1;32m 48\u001b[0m event_description,display_output \u001b[38;5;241m=\u001b[39m steps_display[node]\n\u001b[0;32m---> 49\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(history[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmetadata\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;129;01mor\u001b[39;00m \u001b[43mhistory\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmetadata\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtitle\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m \u001b[38;5;241m!=\u001b[39m event_description: \u001b[38;5;66;03m# if a new step begins\u001b[39;00m\n\u001b[1;32m 50\u001b[0m history\u001b[38;5;241m.\u001b[39mappend(ChatMessage(role\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124massistant\u001b[39m\u001b[38;5;124m\"\u001b[39m, content \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m, metadata\u001b[38;5;241m=\u001b[39m{\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtitle\u001b[39m\u001b[38;5;124m'\u001b[39m :event_description}))\n\u001b[1;32m 52\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m event[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtransform_query\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m event[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mevent\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mon_chat_model_stream\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m node \u001b[38;5;129;01min\u001b[39;00m [\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124manswer_rag\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124manswer_search\u001b[39m\u001b[38;5;124m\"\u001b[39m]:\u001b[38;5;66;03m# if streaming answer\u001b[39;00m\n", "\u001b[0;31mTypeError\u001b[0m: 'Metadata' object is not subscriptable" ] }, { "name": "stdout", "output_type": "stream", "text": [ "---- Categorize_message ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "Output intent categorization: {'intent': 'search'}\n", "\n", "---- Transform query ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "---- Retrieving graphs ----\n", "Subquestion 0: What is radiative forcing and how does it affect climate change?\n", "8 graphs retrieved for subquestion 1: [Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_386', 'returned_content': '', 'source': 'OWID', 'subtitle': \"This is shown as a country or region's share of the global mean surface temperature change as a result of its cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change', 'similarity_score': 0.8423357605934143, 'content': 'Global warming: Contributions to the change in global mean surface temperature', 'reranking_score': 0.005384462885558605, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming: Contributions to the change in global mean surface temperature'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_780', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Nationally determined contributions (NDCs) embody efforts by each country to reduce national emissions and adapt to the impacts of climate change. The Paris Agreement requires each of the 193 Parties to prepare, communicate and maintain NDCs outlining what they intend to achieve. NDCs must be updated every five years.', 'url': 'https://ourworldindata.org/grapher/nationally-determined-contributions', 'similarity_score': 0.8526537418365479, 'content': 'Nationally determined contributions to climate change', 'reranking_score': 7.293858652701601e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Nationally determined contributions to climate change'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_342', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Emissions factors quantify the average CO₂ output per unit of energy. They are measured in kilograms of CO₂ per megawatt-hour (MWh) of energy from various fossil fuel sources.', 'url': 'https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor', 'similarity_score': 0.8662314414978027, 'content': 'Carbon dioxide emissions factors', 'reranking_score': 6.450313958339393e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Carbon dioxide emissions factors'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_358', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contribution-to-temp-rise-by-gas', 'similarity_score': 0.8814464807510376, 'content': 'Contribution to global mean surface temperature rise by gas', 'reranking_score': 2.3544196665170603e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Contribution to global mean surface temperature rise by gas'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_357', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contribution-temp-rise-degrees', 'similarity_score': 0.8828883171081543, 'content': 'Contribution to global mean surface temperature rise', 'reranking_score': 1.724368667055387e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Contribution to global mean surface temperature rise'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_383', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.', 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source', 'similarity_score': 0.8840625286102295, 'content': 'Global warming contributions by gas and source', 'reranking_score': 1.6588734069955535e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming contributions by gas and source'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_767', 'returned_content': '', 'source': 'OWID', 'subtitle': 'This is measured at a nominal depth of 20cm, and given relative to the average temperature from the period of 1961 - 1990. Measured in degrees Celsius.', 'url': 'https://ourworldindata.org/grapher/sea-surface-temperature', 'similarity_score': 0.9009610414505005, 'content': 'Global warming: monthly sea surface temperature anomaly', 'reranking_score': 1.570666063344106e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming: monthly sea surface temperature anomaly'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_768', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The deviation of a specific year's average surface temperature from the 1991-2020 mean, in degrees Celsius.\", 'url': 'https://ourworldindata.org/grapher/global-yearly-surface-temperature-anomalies', 'similarity_score': 0.9119041562080383, 'content': 'Global yearly surface temperature anomalies', 'reranking_score': 1.5241118489939254e-05, 'query_used_for_retrieval': 'What is radiative forcing and how does it affect climate change?', 'sources_used': ['IEA', 'OWID']}, page_content='Global yearly surface temperature anomalies')]\n", "Subquestion 1: What are the specific impacts of radiative forcing on global temperatures and weather patterns?\n", "7 graphs retrieved for subquestion 2: [Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_386', 'returned_content': '', 'source': 'OWID', 'subtitle': \"This is shown as a country or region's share of the global mean surface temperature change as a result of its cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change', 'similarity_score': 0.743827223777771, 'content': 'Global warming: Contributions to the change in global mean surface temperature', 'reranking_score': 0.02035224437713623, 'query_used_for_retrieval': 'What are the specific impacts of radiative forcing on global temperatures and weather patterns?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming: Contributions to the change in global mean surface temperature'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_357', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contribution-temp-rise-degrees', 'similarity_score': 0.7458232045173645, 'content': 'Contribution to global mean surface temperature rise', 'reranking_score': 0.010060282424092293, 'query_used_for_retrieval': 'What are the specific impacts of radiative forcing on global temperatures and weather patterns?', 'sources_used': ['IEA', 'OWID']}, page_content='Contribution to global mean surface temperature rise'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_358', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contribution-to-temp-rise-by-gas', 'similarity_score': 0.7628831267356873, 'content': 'Contribution to global mean surface temperature rise by gas', 'reranking_score': 0.0008739086915738881, 'query_used_for_retrieval': 'What are the specific impacts of radiative forcing on global temperatures and weather patterns?', 'sources_used': ['IEA', 'OWID']}, page_content='Contribution to global mean surface temperature rise by gas'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_768', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The deviation of a specific year's average surface temperature from the 1991-2020 mean, in degrees Celsius.\", 'url': 'https://ourworldindata.org/grapher/global-yearly-surface-temperature-anomalies', 'similarity_score': 0.7884460687637329, 'content': 'Global yearly surface temperature anomalies', 'reranking_score': 0.000565648078918457, 'query_used_for_retrieval': 'What are the specific impacts of radiative forcing on global temperatures and weather patterns?', 'sources_used': ['IEA', 'OWID']}, page_content='Global yearly surface temperature anomalies'), Document(metadata={'category': 'Natural Disasters', 'doc_id': 'owid_1759', 'returned_content': '', 'source': 'OWID', 'subtitle': 'This indicator shows annual anomalies compared with the average precipitation from 1901 to 2000 based on rainfall and snowfall measurements from land-based weather stations worldwide.', 'url': 'https://ourworldindata.org/grapher/global-precipitation-anomaly', 'similarity_score': 0.7976844906806946, 'content': 'Global precipitation anomaly', 'reranking_score': 0.00035785927320830524, 'query_used_for_retrieval': 'What are the specific impacts of radiative forcing on global temperatures and weather patterns?', 'sources_used': ['IEA', 'OWID']}, page_content='Global precipitation anomaly'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_359', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of carbon dioxide, methane, and nitrous oxide. This is for land use and agriculture only.\", 'url': 'https://ourworldindata.org/grapher/global-warming-land', 'similarity_score': 0.8079851269721985, 'content': 'Contribution to global mean surface temperature rise from agriculture and land use', 'reranking_score': 0.00035303618642501533, 'query_used_for_retrieval': 'What are the specific impacts of radiative forcing on global temperatures and weather patterns?', 'sources_used': ['IEA', 'OWID']}, page_content='Contribution to global mean surface temperature rise from agriculture and land use'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_383', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.', 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source', 'similarity_score': 0.8176379203796387, 'content': 'Global warming contributions by gas and source', 'reranking_score': 0.00030412289197556674, 'query_used_for_retrieval': 'What are the specific impacts of radiative forcing on global temperatures and weather patterns?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming contributions by gas and source')]\n", "---- Retrieve documents ----\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "Answer:\n", "Radiative forcing is a key concept in understanding how human activities affect the Earth's climate. It refers to the change in energy balance in the atmosphere due to various factors, primarily greenhouse gases (GHGs) and aerosols. Here’s a breakdown of its impact:\n", "\n", "### Key Points on Radiative Forcing:\n", "\n", "- **Human Influence**: Since the mid-18th century, human activities have significantly increased the concentration of greenhouse gases in the atmosphere, leading to a radiative forcing of approximately 2.72 watts per square meter (W/m²) by 2019. This represents a 19% increase since the last major assessment in 2014, primarily due to rising GHG levels [Doc 1, Doc 3].\n", "\n", "- **Energy Accumulation**: The increase in radiative forcing results in more energy being trapped in the climate system, which leads to warming. The average rate of heating has risen from 0.50 W/m² between 1971 and 2006 to 0.79 W/m² from 2006 to 2018. Most of this heat (91%) is absorbed by the oceans, while land, ice, and the atmosphere account for smaller portions [Doc 2].\n", "\n", "- **Cooling Effects**: While GHGs contribute to warming, aerosols (tiny particles in the atmosphere) can have a cooling effect. However, the overall impact of human-caused radiative forcing is still positive, meaning it leads to net warming [Doc 1].\n", "\n", "- **Future Implications**: The cumulative emissions of CO2 and other gases will determine how much the Earth warms in the future. For instance, limiting warming to 1.5°C above pre-industrial levels will require significant reductions in emissions [Doc 4, Doc 10].\n", "\n", "### Summary of Impacts:\n", "- **Increased Global Temperatures**: The rise in radiative forcing is a major driver of global temperature increases, which can lead to more extreme weather events, rising sea levels, and disruptions to ecosystems.\n", "- **Ocean Warming**: The majority of the heat from increased radiative forcing is absorbed by the oceans, which can affect marine life and weather patterns.\n", "- **Long-term Climate Change**: Continued radiative forcing will have lasting effects on the climate, making it crucial to understand and mitigate these impacts through reduced emissions and other strategies.\n", "\n", "In summary, radiative forcing is a fundamental mechanism by which human activities are changing the climate, primarily through the increase of greenhouse gases, leading to significant warming and associated impacts on the environment and society [Doc 1, Doc 2, Doc 4].\n" ] } ], "source": [ "from climateqa.engine.chains.prompts import audience_prompts\n", "from front.utils import make_html_source,parse_output_llm_with_sources,serialize_docs,make_toolbox,generate_html_graphs\n", "from gradio import ChatMessage\n", "init_prompt = \"\"\n", "\n", "docs = []\n", "docs_used = True\n", "docs_html = \"\"\n", "current_graphs = []\n", "output_query = \"\"\n", "output_language = \"\"\n", "output_keywords = \"\"\n", "gallery = []\n", "updates = []\n", "start_streaming = False\n", "history = [ChatMessage(role=\"assistant\", content=init_prompt)]\n", "steps_display = {\n", " \"categorize_intent\":(\"🔄️ Analyzing user message\",True),\n", " \"transform_query\":(\"🔄️ Thinking step by step to answer the question\",True),\n", " \"retrieve_documents\":(\"🔄️ Searching in the knowledge base\",False),\n", "}\n", "query = \"what is the impact of radiative forcing\"\n", "inputs = {\"user_input\": query,\"audience\": audience_prompts[\"general\"] ,\"sources\": [\"IPCC\", \"IPBES\", \"IPOS\"]}\n", "\n", "result = app.astream_events(inputs,version = \"v1\") #{\"callbacks\":[MyCustomAsyncHandler()]})\n", "\n", "async for event in result:\n", " if \"langgraph_node\" in event[\"metadata\"]:\n", " node = event[\"metadata\"][\"langgraph_node\"]\n", "\n", " if event[\"event\"] == \"on_chain_end\" and event[\"name\"] == \"retrieve_documents\" :# when documents are retrieved\n", " try:\n", " docs = event[\"data\"][\"output\"][\"documents\"]\n", " docs_html = []\n", " for i, d in enumerate(docs, 1):\n", " docs_html.append(make_html_source(d, i))\n", " \n", " used_documents = used_documents + [d.metadata[\"name\"] for d in docs]\n", " history[-1].content = \"Adding sources :\\n\\n - \" + \"\\n - \".join(np.unique(used_documents))\n", " \n", " docs_html = \"\".join(docs_html)\n", " \n", " except Exception as e:\n", " print(f\"Error getting documents: {e}\")\n", " print(event)\n", "\n", " elif event[\"name\"] in steps_display.keys() and event[\"event\"] == \"on_chain_start\": #display steps\n", " event_description,display_output = steps_display[node]\n", " if not hasattr(history[-1], 'metadata') or history[-1].metadata[\"title\"] != event_description: # if a new step begins\n", " history.append(ChatMessage(role=\"assistant\", content = \"\", metadata={'title' :event_description}))\n", "\n", " elif event[\"name\"] != \"transform_query\" and event[\"event\"] == \"on_chat_model_stream\" and node in [\"answer_rag\", \"answer_search\"]:# if streaming answer\n", " if start_streaming == False:\n", " start_streaming = True\n", " history.append(ChatMessage(role=\"assistant\", content = \"\"))\n", " answer_message_content += event[\"data\"][\"chunk\"].content\n", " answer_message_content = parse_output_llm_with_sources(answer_message_content)\n", " history[-1] = ChatMessage(role=\"assistant\", content = answer_message_content)\n", " \n", " elif event[\"name\"] in [\"retrieve_graphs\", \"retrieve_graphs_ai\"] and event[\"event\"] == \"on_chain_end\":\n", " try:\n", " recommended_content = event[\"data\"][\"output\"][\"recommended_content\"]\n", " # graphs = [\n", " # {\n", " # \"embedding\": x.metadata[\"returned_content\"],\n", " # \"metadata\": {\n", " # \"source\": x.metadata[\"source\"],\n", " # \"category\": x.metadata[\"category\"]\n", " # }\n", " # } for x in recommended_content if x.metadata[\"source\"] == \"OWID\"\n", " # ]\n", " \n", " unique_graphs = []\n", " seen_embeddings = set()\n", "\n", " for x in recommended_content:\n", " embedding = x.metadata[\"returned_content\"]\n", " \n", " # Check if the embedding has already been seen\n", " if embedding not in seen_embeddings:\n", " unique_graphs.append({\n", " \"embedding\": embedding,\n", " \"metadata\": {\n", " \"source\": x.metadata[\"source\"],\n", " \"category\": x.metadata[\"category\"]\n", " }\n", " })\n", " # Add the embedding to the seen set\n", " seen_embeddings.add(embedding)\n", "\n", "\n", " categories = {}\n", " for graph in unique_graphs:\n", " category = graph['metadata']['category']\n", " if category not in categories:\n", " categories[category] = []\n", " categories[category].append(graph['embedding'])\n", "\n", " # graphs_html = \"\"\n", " for category, embeddings in categories.items():\n", " # graphs_html += f\"

{category}

\"\n", " # current_graphs.append(f\"

{category}

\")\n", " for embedding in embeddings:\n", " current_graphs.append([embedding, category])\n", " # graphs_html += f\"
{embedding}
\"\n", " \n", " except Exception as e:\n", " print(f\"Error getting graphs: {e}\")\n", "\n", " \n", " \n", " \n", " \n", " \n", " # ### old\n", " # if event[\"event\"] == \"on_chat_model_stream\" and event[\"metadata\"][\"langgraph_node\"] in [\"answer_rag\", \"answer_rag_no_docs\", \"answer_chitchat\", \"answer_ai_impact\"]:\n", " # if start_streaming == False:\n", " # start_streaming = True\n", " # history.append(ChatMessage(role=\"assistant\", content = \"\"))\n", "\n", " # answer_message_content += event[\"data\"][\"chunk\"].content\n", " # answer_message_content = parse_output_llm_with_sources(answer_message_content)\n", " # history[-1] = ChatMessage(role=\"assistant\", content = answer_message_content)\n", "\n", "\n", " # if docs_used is True and event[\"metadata\"][\"langgraph_node\"] in [\"answer_rag_no_docs\", \"answer_chitchat\", \"answer_ai_impact\"]:\n", " # docs_used = False\n", " \n", " # elif docs_used is True and event[\"name\"] == \"retrieve_documents\" and event[\"event\"] == \"on_chain_end\":\n", " # try:\n", " # docs = event[\"data\"][\"output\"][\"documents\"]\n", " # docs_html = []\n", " # for i, d in enumerate(docs, 1):\n", " # docs_html.append(make_html_source(d, i))\n", " # docs_html = \"\".join(docs_html)\n", "\n", " # except Exception as e:\n", " # print(f\"Error getting documents: {e}\")\n", " # print(event)\n", "\n", " # elif event[\"name\"] == \"retrieve_documents\" and event[\"event\"] == \"on_chain_start\":\n", " # print(event)\n", " # questions = event[\"data\"][\"input\"][\"questions\"]\n", " # questions = \"\\n\".join([f\"{i+1}. {q['question']} ({q['source']})\" for i,q in enumerate(questions)])\n", " # answer_yet = \"🔄️ Searching in the knowledge base\\n{questions}\"\n", " # history[-1] = (query,answer_yet)\n", "\n", " # elif event[\"name\"] in [\"retrieve_graphs\", \"retrieve_graphs_ai\"] and event[\"event\"] == \"on_chain_end\":\n", " # try:\n", " # recommended_content = event[\"data\"][\"output\"][\"recommended_content\"]\n", " # # graphs = [\n", " # # {\n", " # # \"embedding\": x.metadata[\"returned_content\"],\n", " # # \"metadata\": {\n", " # # \"source\": x.metadata[\"source\"],\n", " # # \"category\": x.metadata[\"category\"]\n", " # # }\n", " # # } for x in recommended_content if x.metadata[\"source\"] == \"OWID\"\n", " # # ]\n", " \n", " # unique_graphs = []\n", " # seen_embeddings = set()\n", "\n", " # for x in recommended_content:\n", " # embedding = x.metadata[\"returned_content\"]\n", " \n", " # # Check if the embedding has already been seen\n", " # if embedding not in seen_embeddings:\n", " # unique_graphs.append({\n", " # \"embedding\": embedding,\n", " # \"metadata\": {\n", " # \"source\": x.metadata[\"source\"],\n", " # \"category\": x.metadata[\"category\"]\n", " # }\n", " # })\n", " # # Add the embedding to the seen set\n", " # seen_embeddings.add(embedding)\n", "\n", "\n", " # categories = {}\n", " # for graph in unique_graphs:\n", " # category = graph['metadata']['category']\n", " # if category not in categories:\n", " # categories[category] = []\n", " # categories[category].append(graph['embedding'])\n", "\n", " # # graphs_html = \"\"\n", " # for category, embeddings in categories.items():\n", " # # graphs_html += f\"

{category}

\"\n", " # # current_graphs.append(f\"

{category}

\")\n", " # for embedding in embeddings:\n", " # current_graphs.append([embedding, category])\n", " # # graphs_html += f\"
{embedding}
\"\n", " \n", " # except Exception as e:\n", " # print(f\"Error getting graphs: {e}\")\n", "\n", " # elif event[\"name\"] in steps_display.keys() and event[\"event\"] == \"on_chain_start\": #display steps\n", " # node = event[\"metadata\"][\"langgraph_node\"]\n", " # event_description,display_output = steps_display[node]\n", " # if not hasattr(history[-1], 'metadata') or history[-1].metadata[\"title\"] != event_description: # if a new step begins\n", " # history.append(ChatMessage(role=\"assistant\", content = \"\", metadata={'title' :event_description}))\n", "\n", " # for event_name,(event_description,display_output) in steps_display.items():\n", " # if event[\"name\"] == event_name:\n", " # if event[\"event\"] == \"on_chain_start\":\n", " # # answer_yet = f\"

{event_description}

\"\n", " # # answer_yet = make_toolbox(event_description, \"\", checked = False)\n", " # answer_yet = event_description\n", "\n", " # history[-1] = (query,answer_yet)\n", " # elif event[\"event\"] == \"on_chain_end\":\n", " # answer_yet = \"\"\n", " # history[-1] = (query,answer_yet)\n", " # if display_output:\n", " # print(event[\"data\"][\"output\"])\n", "\n", " # if op['path'] == path_reformulation: # reforulated question\n", " # try:\n", " # output_language = op['value'][\"language\"] # str\n", " # output_query = op[\"value\"][\"question\"]\n", " # except Exception as e:\n", " # raise gr.Error(f\"ClimateQ&A Error: {e} - The error has been noted, try another question and if the error remains, you can contact us :)\")\n", " \n", " # if op[\"path\"] == path_keywords:\n", " # try:\n", " # output_keywords = op['value'][\"keywords\"] # str\n", " # output_keywords = \" AND \".join(output_keywords)\n", " # except Exception as e:\n", " # pass\n", "\n", "\n", "\n", " # history = [tuple(x) for x in history]" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "---- Categorize_message ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "Output intent categorization: {'intent': 'search'}\n", "\n", "---- Transform query ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "---- Retrieving graphs ----\n", "Subquestion 0: What are the effects of climate change on the environment?\n", "8 graphs retrieved for subquestion 1: [Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_349', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Consumption-based emissions are national emissions that have been adjusted for trade. This measures fossil fuel and industry emissions. Land-use change is not included.', 'url': 'https://ourworldindata.org/grapher/co2-emissions-and-gdp', 'similarity_score': 0.7941333055496216, 'content': 'Change in CO2 emissions and GDP', 'reranking_score': 0.279598593711853, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Change in CO2 emissions and GDP'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_780', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Nationally determined contributions (NDCs) embody efforts by each country to reduce national emissions and adapt to the impacts of climate change. The Paris Agreement requires each of the 193 Parties to prepare, communicate and maintain NDCs outlining what they intend to achieve. NDCs must be updated every five years.', 'url': 'https://ourworldindata.org/grapher/nationally-determined-contributions', 'similarity_score': 0.7979490756988525, 'content': 'Nationally determined contributions to climate change', 'reranking_score': 0.012760520912706852, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Nationally determined contributions to climate change'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_756', 'returned_content': '', 'source': 'OWID', 'subtitle': 'National adaptation plans are a means of identifying medium- and long-term climate change adaptation needs and developing and implementing strategies and programmes to address those needs.', 'url': 'https://ourworldindata.org/grapher/countries-with-national-adaptation-plans-for-climate-change', 'similarity_score': 0.7981775999069214, 'content': 'Countries with national adaptation plans for climate change', 'reranking_score': 0.004124350380152464, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Countries with national adaptation plans for climate change'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_386', 'returned_content': '', 'source': 'OWID', 'subtitle': \"This is shown as a country or region's share of the global mean surface temperature change as a result of its cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change', 'similarity_score': 0.7989407181739807, 'content': 'Global warming: Contributions to the change in global mean surface temperature', 'reranking_score': 0.0036289971321821213, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming: Contributions to the change in global mean surface temperature'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_383', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.', 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source', 'similarity_score': 0.8071538805961609, 'content': 'Global warming contributions by gas and source', 'reranking_score': 0.0016414257697761059, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming contributions by gas and source'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_350', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Consumption-based emissions include those from fossil fuels and industry. Land-use change emissions are not included.', 'url': 'https://ourworldindata.org/grapher/co2-emissions-and-gdp-per-capita', 'similarity_score': 0.8269157409667969, 'content': 'Change in per capita CO2 emissions and GDP', 'reranking_score': 0.00023705528292339295, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Change in per capita CO2 emissions and GDP'), Document(metadata={'category': 'Biodiversity', 'doc_id': 'owid_199', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The number of species at risk of losing greater than 25% of their habitat as a result of agricultural expansion under business-as-usual projections to 2050. This is shown for countries with more than 25 species at risk.', 'url': 'https://ourworldindata.org/grapher/habitat-loss-25-species', 'similarity_score': 0.8301026225090027, 'content': 'Countries with more than 25 species at risk of losing more than 25% of their habitat by 2050', 'reranking_score': 7.497359911212698e-05, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Countries with more than 25 species at risk of losing more than 25% of their habitat by 2050'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_782', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Share of young people in each surveyed country that responded \"yes\" to each statement about climate change. 1,000 young people, aged 16 to 25 years old, were surveyed in each country.', 'url': 'https://ourworldindata.org/grapher/opinions-young-people-climate', 'similarity_score': 0.8306424617767334, 'content': 'Opinions of young people on the threats of climate change', 'reranking_score': 2.747046346485149e-05, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Opinions of young people on the threats of climate change')]\n", "Subquestion 1: How does climate change affect human health and society?\n", "7 graphs retrieved for subquestion 2: [Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_789', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Participants were asked to score beliefs on a scale from 0 to 100 on four questions: whether action was necessary to avoid a global catastrophe; humans were causing climate change; it was a serious threat to humanity; and was a global emergency.', 'url': 'https://ourworldindata.org/grapher/share-believe-climate', 'similarity_score': 0.7580230236053467, 'content': \"Share of people who believe in climate change and think it's a serious threat to humanity\", 'reranking_score': 0.005214352160692215, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IEA', 'OWID']}, page_content=\"Share of people who believe in climate change and think it's a serious threat to humanity\"), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_782', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Share of young people in each surveyed country that responded \"yes\" to each statement about climate change. 1,000 young people, aged 16 to 25 years old, were surveyed in each country.', 'url': 'https://ourworldindata.org/grapher/opinions-young-people-climate', 'similarity_score': 0.8168312311172485, 'content': 'Opinions of young people on the threats of climate change', 'reranking_score': 0.004852706100791693, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IEA', 'OWID']}, page_content='Opinions of young people on the threats of climate change'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_756', 'returned_content': '', 'source': 'OWID', 'subtitle': 'National adaptation plans are a means of identifying medium- and long-term climate change adaptation needs and developing and implementing strategies and programmes to address those needs.', 'url': 'https://ourworldindata.org/grapher/countries-with-national-adaptation-plans-for-climate-change', 'similarity_score': 0.8196202516555786, 'content': 'Countries with national adaptation plans for climate change', 'reranking_score': 0.0012044497998431325, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IEA', 'OWID']}, page_content='Countries with national adaptation plans for climate change'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_386', 'returned_content': '', 'source': 'OWID', 'subtitle': \"This is shown as a country or region's share of the global mean surface temperature change as a result of its cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change', 'similarity_score': 0.8402930498123169, 'content': 'Global warming: Contributions to the change in global mean surface temperature', 'reranking_score': 0.00041706717456690967, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming: Contributions to the change in global mean surface temperature'), Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_780', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Nationally determined contributions (NDCs) embody efforts by each country to reduce national emissions and adapt to the impacts of climate change. The Paris Agreement requires each of the 193 Parties to prepare, communicate and maintain NDCs outlining what they intend to achieve. NDCs must be updated every five years.', 'url': 'https://ourworldindata.org/grapher/nationally-determined-contributions', 'similarity_score': 0.8433299660682678, 'content': 'Nationally determined contributions to climate change', 'reranking_score': 0.00030759291257709265, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IEA', 'OWID']}, page_content='Nationally determined contributions to climate change'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_357', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contribution-temp-rise-degrees', 'similarity_score': 0.8584674596786499, 'content': 'Contribution to global mean surface temperature rise', 'reranking_score': 0.00025533974985592067, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IEA', 'OWID']}, page_content='Contribution to global mean surface temperature rise'), Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_317', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Percentage change in gross domestic product (GDP), population, and carbon dioxide (CO₂) emissions.', 'url': 'https://ourworldindata.org/grapher/co2-gdp-pop-growth', 'similarity_score': 0.8730868697166443, 'content': 'Annual change in GDP, population and CO2 emissions', 'reranking_score': 0.0002404096449026838, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IEA', 'OWID']}, page_content='Annual change in GDP, population and CO2 emissions')]\n", "---- Retrieve documents ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_start callback: ValidationError(model='Run', errors=[{'loc': ('__root__',), 'msg': \"argument of type 'NoneType' is not iterable\", 'type': 'type_error'}])\n", "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_end callback: TracerException('No indexed run ID aa00a789-394b-42e1-922b-28d51bd4c441.')\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "---- Retrieve documents ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_start callback: ValidationError(model='Run', errors=[{'loc': ('__root__',), 'msg': \"argument of type 'NoneType' is not iterable\", 'type': 'type_error'}])\n", "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_end callback: TracerException('No indexed run ID 511833e2-a8c6-4d5f-ace1-cb7978dcf3e7.')\n", "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_start callback: ValidationError(model='Run', errors=[{'loc': ('__root__',), 'msg': \"argument of type 'NoneType' is not iterable\", 'type': 'type_error'}])\n", "WARNING:langchain_core.callbacks.manager:Error in LangChainTracer.on_chain_end callback: TracerException('No indexed run ID 561b415c-c77e-4ed7-82c8-9963ec1d1c7d.')\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "---- Answer RAG ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "Answer:\n", "Climate change has profound and multifaceted impacts on both human systems and the natural environment, with significant implications for health, biodiversity, agriculture, and infrastructure. Here are the key impacts:\n", "\n", "### 1. **Human Health**\n", "- **Physical and Mental Health**: Climate change adversely affects physical health globally, leading to increased mortality and morbidity due to extreme heat events. It also exacerbates mental health issues, particularly in vulnerable populations [Doc 1, Doc 11].\n", "- **Disease Dynamics**: There is a notable increase in climate-related diseases, including vector-borne diseases (e.g., malaria, dengue) due to the expansion of disease vectors. Additionally, the incidence of water- and food-borne diseases has risen, influenced by higher temperatures and increased rainfall, which can lead to outbreaks of diseases like cholera [Doc 1, Doc 13].\n", "- **Food Security and Nutrition**: Climate change impacts food production through altered agricultural yields, which can lead to malnutrition and food insecurity, particularly in regions already facing challenges [Doc 2, Doc 6].\n", "\n", "### 2. **Biodiversity and Ecosystems**\n", "- **Species and Habitat Changes**: Climate change drives shifts in species ranges, habitat locations, and seasonal timing, which can lead to biodiversity loss. Many species are unable to adapt or migrate quickly enough to cope with the rapid changes [Doc 4, Doc 9].\n", "- **Ecosystem Functionality**: Changes in climate affect critical ecosystem functions such as water regulation, food production, and carbon sequestration. This can lead to decreased resilience of ecosystems and increased vulnerability to other stressors like pollution and habitat degradation [Doc 5, Doc 9].\n", "\n", "### 3. **Agriculture and Food Production**\n", "- **Agricultural Yields**: Climate change directly affects agricultural productivity through changes in temperature, precipitation patterns, and CO2 concentrations. These changes can lead to reduced crop yields and increased pest populations, further threatening food security [Doc 6, Doc 10].\n", "- **Land Degradation**: The interaction of climate change with other drivers of land degradation is expected to exacerbate the extent and severity of land degradation, complicating restoration efforts and necessitating new adaptive strategies [Doc 6].\n", "\n", "### 4. **Infrastructure and Urban Areas**\n", "- **Impact on Cities**: Urban areas are particularly vulnerable to climate change, experiencing intensified heatwaves, flooding, and other extreme weather events. These impacts can compromise infrastructure, disrupt services, and lead to significant economic losses, disproportionately affecting marginalized communities [Doc 11, Doc 10].\n", "- **Economic Implications**: The economic sectors are also at risk, with climate change causing damage to cities and infrastructure, which can hinder development and adaptation efforts [Doc 2, Doc 10].\n", "\n", "### 5. **Interconnectedness of Impacts**\n", "- The effects of climate change are compounded by interactions with other environmental, socio-cultural, political, and economic drivers, making the challenges more complex and requiring integrated approaches for mitigation and adaptation [Doc 12, Doc 10].\n", "\n", "In summary, climate change poses significant risks across various domains, necessitating urgent action to mitigate its impacts and adapt to the changing conditions. The interplay between health, biodiversity, agriculture, and infrastructure highlights the need for comprehensive strategies to address these interconnected challenges.\n" ] }, { "data": { "text/plain": [ "{'user_input': 'what is the impact of climate change ?',\n", " 'language': 'English',\n", " 'intent': 'search',\n", " 'query': 'what is the impact of climate change ?',\n", " 'remaining_questions': [],\n", " 'n_questions': 2,\n", " 'answer': 'Climate change has profound and multifaceted impacts on both human systems and the natural environment, with significant implications for health, biodiversity, agriculture, and infrastructure. Here are the key impacts:\\n\\n### 1. **Human Health**\\n- **Physical and Mental Health**: Climate change adversely affects physical health globally, leading to increased mortality and morbidity due to extreme heat events. It also exacerbates mental health issues, particularly in vulnerable populations [Doc 1, Doc 11].\\n- **Disease Dynamics**: There is a notable increase in climate-related diseases, including vector-borne diseases (e.g., malaria, dengue) due to the expansion of disease vectors. Additionally, the incidence of water- and food-borne diseases has risen, influenced by higher temperatures and increased rainfall, which can lead to outbreaks of diseases like cholera [Doc 1, Doc 13].\\n- **Food Security and Nutrition**: Climate change impacts food production through altered agricultural yields, which can lead to malnutrition and food insecurity, particularly in regions already facing challenges [Doc 2, Doc 6].\\n\\n### 2. **Biodiversity and Ecosystems**\\n- **Species and Habitat Changes**: Climate change drives shifts in species ranges, habitat locations, and seasonal timing, which can lead to biodiversity loss. Many species are unable to adapt or migrate quickly enough to cope with the rapid changes [Doc 4, Doc 9].\\n- **Ecosystem Functionality**: Changes in climate affect critical ecosystem functions such as water regulation, food production, and carbon sequestration. This can lead to decreased resilience of ecosystems and increased vulnerability to other stressors like pollution and habitat degradation [Doc 5, Doc 9].\\n\\n### 3. **Agriculture and Food Production**\\n- **Agricultural Yields**: Climate change directly affects agricultural productivity through changes in temperature, precipitation patterns, and CO2 concentrations. These changes can lead to reduced crop yields and increased pest populations, further threatening food security [Doc 6, Doc 10].\\n- **Land Degradation**: The interaction of climate change with other drivers of land degradation is expected to exacerbate the extent and severity of land degradation, complicating restoration efforts and necessitating new adaptive strategies [Doc 6].\\n\\n### 4. **Infrastructure and Urban Areas**\\n- **Impact on Cities**: Urban areas are particularly vulnerable to climate change, experiencing intensified heatwaves, flooding, and other extreme weather events. These impacts can compromise infrastructure, disrupt services, and lead to significant economic losses, disproportionately affecting marginalized communities [Doc 11, Doc 10].\\n- **Economic Implications**: The economic sectors are also at risk, with climate change causing damage to cities and infrastructure, which can hinder development and adaptation efforts [Doc 2, Doc 10].\\n\\n### 5. **Interconnectedness of Impacts**\\n- The effects of climate change are compounded by interactions with other environmental, socio-cultural, political, and economic drivers, making the challenges more complex and requiring integrated approaches for mitigation and adaptation [Doc 12, Doc 10].\\n\\nIn summary, climate change poses significant risks across various domains, necessitating urgent action to mitigate its impacts and adapt to the changing conditions. The interplay between health, biodiversity, agriculture, and infrastructure highlights the need for comprehensive strategies to address these interconnected challenges.',\n", " 'audience': 'scientifique',\n", " 'documents': [Document(metadata={'chunk_type': 'text', 'document_id': 'document4', 'document_number': 4.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 34.0, 'name': 'Summary for Policymakers. In: Climate Change 2022: Impacts, Adaptation and Vulnerability. Contribution of the WGII to the AR6 of the IPCC', 'num_characters': 1223.0, 'num_tokens': 225.0, 'num_tokens_approx': 272.0, 'num_words': 204.0, 'page_number': 11, 'release_date': 2022.0, 'report_type': 'SPM', 'section_header': '(b) Observed impacts of climate change on human systems', 'short_name': 'IPCC AR6 WGII SPM', 'source': 'IPCC', 'toc_level0': 'B: Observed and Projected Impacts and Risks', 'toc_level1': 'Observed Impacts from Climate Change', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://www.ipcc.ch/report/ar6/wg2/downloads/report/IPCC_AR6_WGII_SummaryForPolicymakers.pdf', 'similarity_score': 0.783784747, 'content': 'B.1.4 Climate change has adversely affected physical health of people globally (very high confidence) and mental health of people in the assessed regions (very high confidence). Climate change impacts on health are mediated through natural and human systems, including economic and social conditions and disruptions (high confidence). In all regions extreme heat events have resulted in human mortality and morbidity (very high confidence). The occurrence of climate-related food-borne and water-borne diseases has increased (very high confidence). The incidence of vector-borne diseases has increased from range expansion and/or increased reproduction of disease vectors (high confidence). Animal and human diseases, including zoonoses, are emerging in new areas (high confidence). Water and food-borne disease risks have increased regionally from climate-sensitive aquatic pathogens, including Vibrio spp. (high confidence), and from toxic substances from harmful freshwater cyanobacteria (medium confidence). Although diarrheal diseases have decreased globally, higher temperatures, increased rain and flooding have increased the occurrence of diarrheal diseases, including cholera (very high confidence)', 'reranking_score': 0.9999046325683594, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'How does climate change affect human health and society?', 'index_used': 'Vector'}, page_content='B.1.4 Climate change has adversely affected physical health of people globally (very high confidence) and mental health of people in the assessed regions (very high confidence). Climate change impacts on health are mediated through natural and human systems, including economic and social conditions and disruptions (high confidence). In all regions extreme heat events have resulted in human mortality and morbidity (very high confidence). The occurrence of climate-related food-borne and water-borne diseases has increased (very high confidence). The incidence of vector-borne diseases has increased from range expansion and/or increased reproduction of disease vectors (high confidence). Animal and human diseases, including zoonoses, are emerging in new areas (high confidence). Water and food-borne disease risks have increased regionally from climate-sensitive aquatic pathogens, including Vibrio spp. (high confidence), and from toxic substances from harmful freshwater cyanobacteria (medium confidence). Although diarrheal diseases have decreased globally, higher temperatures, increased rain and flooding have increased the occurrence of diarrheal diseases, including cholera (very high confidence)'),\n", " Document(metadata={'chunk_type': 'image', 'document_id': 'document4', 'document_number': 4.0, 'element_id': 'Picture_1_9', 'figure_code': 'Figure SPM.2', 'file_size': 221.7900390625, 'image_path': '/dbfs/mnt/ai4sclqa/raw/climateqa/documents/document4/images/Picture_1_9.png', 'n_pages': 34.0, 'name': 'Summary for Policymakers. In: Climate Change 2022: Impacts, Adaptation and Vulnerability. Contribution of the WGII to the AR6 of the IPCC', 'num_characters': 'N/A', 'num_tokens': 'N/A', 'num_tokens_approx': 'N/A', 'num_words': 'N/A', 'page_number': 10, 'release_date': 2022.0, 'report_type': 'SPM', 'section_header': 'N/A', 'short_name': 'IPCC AR6 WGII SPM', 'source': 'IPCC', 'toc_level0': 'B: Observed and Projected Impacts and Risks', 'toc_level1': 'Observed Impacts from Climate Change', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://www.ipcc.ch/report/ar6/wg2/downloads/report/IPCC_AR6_WGII_SummaryForPolicymakers.pdf', 'similarity_score': 0.753355443, 'content': \"Summary: This visual summarizes the observed impacts of climate change on various human systems across different global regions, including effects on water scarcity, food production (agriculture, livestock, fisheries), human health (infectious diseases, malnutrition, mental health), displacement, and the damage to cities, infrastructure, and economic sectors. The graphic highlights the degree of confidence in the attribution of these impacts to climate change, with varied confidence levels indicated by the color and filling of symbols for global assessments and regional assessments. Each region's row indicates the observed impacts, allowing a comparison of how climate change has differentially affected human systems around the world.\", 'reranking_score': 0.9998388290405273, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'How does climate change affect human health and society?', 'index_used': 'Vector'}, page_content=\"Summary: This visual summarizes the observed impacts of climate change on various human systems across different global regions, including effects on water scarcity, food production (agriculture, livestock, fisheries), human health (infectious diseases, malnutrition, mental health), displacement, and the damage to cities, infrastructure, and economic sectors. The graphic highlights the degree of confidence in the attribution of these impacts to climate change, with varied confidence levels indicated by the color and filling of symbols for global assessments and regional assessments. Each region's row indicates the observed impacts, allowing a comparison of how climate change has differentially affected human systems around the world.\"),\n", " Document(metadata={'chunk_type': 'text', 'document_id': 'document10', 'document_number': 10.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 36.0, 'name': 'Synthesis report of the IPCC Sixth Assesment Report AR6', 'num_characters': 416.0, 'num_tokens': 74.0, 'num_tokens_approx': 84.0, 'num_words': 63.0, 'page_number': 13, 'release_date': 2023.0, 'report_type': 'SPM', 'section_header': 'Observed Changes and Impacts', 'short_name': 'IPCC AR6 SYR', 'source': 'IPCC', 'toc_level0': 'N/A', 'toc_level1': 'N/A', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://www.ipcc.ch/report/ar6/syr/downloads/report/IPCC_AR6_SYR_SPM.pdf', 'similarity_score': 0.739644825, 'content': 'Adverse impacts from human-caused climate change will continue to intensify\\na) Observed widespread and substantial impacts and related losses and damages attributed to climate change\\nHealth and well-being\\nWater availability and food production \\nCities, settlements and infrastructure\\nb) Impacts are driven by changes in multiple physical climate conditions, which are increasingly attributed to human influence', 'reranking_score': 0.9997883439064026, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'How does climate change affect human health and society?', 'index_used': 'Vector'}, page_content='Adverse impacts from human-caused climate change will continue to intensify\\na) Observed widespread and substantial impacts and related losses and damages attributed to climate change\\nHealth and well-being\\nWater availability and food production \\nCities, settlements and infrastructure\\nb) Impacts are driven by changes in multiple physical climate conditions, which are increasingly attributed to human influence'),\n", " Document(metadata={'chunk_type': 'text', 'document_id': 'document34', 'document_number': 34.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 52.0, 'name': 'Summary for Policymakers. Regional Assessment Report on Biodiversity and Ecosystem Services for Europe and Central Asia', 'num_characters': 827.0, 'num_tokens': 206.0, 'num_tokens_approx': 226.0, 'num_words': 170.0, 'page_number': 30, 'release_date': 2018.0, 'report_type': 'SPM', 'section_header': \"Figure SPM 8 Trends in direct drivers of biodiversity and nature's contributions to people in the \\r\\nlast 20 years.\", 'short_name': 'IPBES RAR ECA SPM', 'source': 'IPBES', 'toc_level0': 'N/A', 'toc_level1': 'N/A', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://zenodo.org/record/3237468/files/ipbes_assessment_spm_eca_EN.pdf', 'similarity_score': 0.742851615, 'content': 'Climate change shifts seasonal timing, growth and productivity, species ranges and habitat location, which affects biodiversity, agriculture, forestry, and fisheries (well \\nestablished) {4.7.1.1, 4.7.1.3}. Many species will not migrate or adapt fast enough to keep pace with projected rates of climate change (established but incomplete) {4.7.1}. Droughts decrease biomass productivity, increase biodiversity loss and net carbon flux to the atmosphere, and decrease water quality in aquatic systems (established but incomplete) {4.7.1.2, 5.2}. Climate change causes ocean acidification, rising sea levels and changes ocean stratification, reducing biodiversity, growth and productivity, impairing fisheries and increasing CO2 release into the atmosphere (established but incomplete) {4.7.1.1, 4.7.1.3}.', 'reranking_score': 0.9997496008872986, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'What are the effects of climate change on the environment?', 'index_used': 'Vector'}, page_content='Climate change shifts seasonal timing, growth and productivity, species ranges and habitat location, which affects biodiversity, agriculture, forestry, and fisheries (well \\nestablished) {4.7.1.1, 4.7.1.3}. Many species will not migrate or adapt fast enough to keep pace with projected rates of climate change (established but incomplete) {4.7.1}. Droughts decrease biomass productivity, increase biodiversity loss and net carbon flux to the atmosphere, and decrease water quality in aquatic systems (established but incomplete) {4.7.1.2, 5.2}. Climate change causes ocean acidification, rising sea levels and changes ocean stratification, reducing biodiversity, growth and productivity, impairing fisheries and increasing CO2 release into the atmosphere (established but incomplete) {4.7.1.1, 4.7.1.3}.'),\n", " Document(metadata={'chunk_type': 'text', 'document_id': 'document30', 'document_number': 30.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 44.0, 'name': 'Summary for Policymakers. Regional Assessment Report on Biodiversity and Ecosystem Services for the Americas', 'num_characters': 886.0, 'num_tokens': 173.0, 'num_tokens_approx': 194.0, 'num_words': 146.0, 'page_number': 15, 'release_date': 2018.0, 'report_type': 'SPM', 'section_header': \"C. DRIVERS OF TRENDS IN \\r\\nBIODIVERSITY AND NATURE'S \\r\\nCONTRIBUTIONS TO PEOPLE\", 'short_name': 'IPBES RAR AM SPM', 'source': 'IPBES', 'toc_level0': 'N/A', 'toc_level1': 'N/A', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://zenodo.org/record/3236292/files/ipbes_assessment_spm_americas_EN.pdf', 'similarity_score': 0.734894216, 'content': \"C4 Human-induced climate change is becoming an increasingly important direct driver, amplifying the impacts of other drivers (i.e., habitat degradation, pollution, invasive species and overexploitation) through changes in temperature, precipitation and the nature of some extreme events. Regional changes in temperature of the atmosphere and the ocean will be accompanied by changes in glacial extent, rainfall, river discharge, wind and ocean currents and sea level, among many other environmental features, which, on balance, have had adverse impacts on biodiversity and nature's contributions to people. The majority of ecosystems in the Americas have already experienced increased mean and extreme temperatures and/or, in some places, mean and \\nextreme precipitation, causing changes in species distributions and interactions and in ecosystem boundaries.\", 'reranking_score': 0.9997311234474182, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'What are the effects of climate change on the environment?', 'index_used': 'Vector'}, page_content=\"C4 Human-induced climate change is becoming an increasingly important direct driver, amplifying the impacts of other drivers (i.e., habitat degradation, pollution, invasive species and overexploitation) through changes in temperature, precipitation and the nature of some extreme events. Regional changes in temperature of the atmosphere and the ocean will be accompanied by changes in glacial extent, rainfall, river discharge, wind and ocean currents and sea level, among many other environmental features, which, on balance, have had adverse impacts on biodiversity and nature's contributions to people. The majority of ecosystems in the Americas have already experienced increased mean and extreme temperatures and/or, in some places, mean and \\nextreme precipitation, causing changes in species distributions and interactions and in ecosystem boundaries.\"),\n", " Document(metadata={'chunk_type': 'text', 'document_id': 'document36', 'document_number': 36.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 48.0, 'name': 'Summary for Policymakers. Assessment Report on Land Degradation and Restoration', 'num_characters': 978.0, 'num_tokens': 211.0, 'num_tokens_approx': 248.0, 'num_words': 186.0, 'page_number': 34, 'release_date': 2018.0, 'report_type': 'SPM', 'section_header': 'Figure SPM 11 Illustration of the biodiversity impacts of international trade in 2000. ', 'short_name': 'IPBES AR LDR SPM', 'source': 'IPBES', 'toc_level0': 'N/A', 'toc_level1': 'N/A', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://zenodo.org/records/3237411/files/ipbes_assessment_spm_ldra_EN.pdf?download=1', 'similarity_score': 0.727124453, 'content': '25 Climate change threatens to become an increasingly important driver of land degradation throughout the twenty-first century, exacerbating both the extent and severity of land degradation as well as reducing the effectiveness and sustainability of restoration options {3.4}. Climate change can have a direct effect on agricultural yields, through changes in the means and extremes of temperature, precipitation and CO2 concentrations, as well as on species distributions and population dynamics, for instance, pest species {3.4.1, 3.4.2, 3.4.4, 4.2.8, 7.2.6}. However, the greatest effects of climate change on land is likely to come from interactions with other degradation drivers {3.4.5}. Long-established sustainable land management and restoration practices may no longer be viable under future climatic regimes in the places where they were developed, requiring rapid adaptation and innovation, but also opening new opportunities {3.5}.', 'reranking_score': 0.9997143149375916, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'What are the effects of climate change on the environment?', 'index_used': 'Vector'}, page_content='25 Climate change threatens to become an increasingly important driver of land degradation throughout the twenty-first century, exacerbating both the extent and severity of land degradation as well as reducing the effectiveness and sustainability of restoration options {3.4}. Climate change can have a direct effect on agricultural yields, through changes in the means and extremes of temperature, precipitation and CO2 concentrations, as well as on species distributions and population dynamics, for instance, pest species {3.4.1, 3.4.2, 3.4.4, 4.2.8, 7.2.6}. However, the greatest effects of climate change on land is likely to come from interactions with other degradation drivers {3.4.5}. Long-established sustainable land management and restoration practices may no longer be viable under future climatic regimes in the places where they were developed, requiring rapid adaptation and innovation, but also opening new opportunities {3.5}.'),\n", " Document(metadata={'chunk_type': 'text', 'document_id': 'document30', 'document_number': 30.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 44.0, 'name': 'Summary for Policymakers. Regional Assessment Report on Biodiversity and Ecosystem Services for the Americas', 'num_characters': 290.0, 'num_tokens': 65.0, 'num_tokens_approx': 77.0, 'num_words': 58.0, 'page_number': 29, 'release_date': 2018.0, 'report_type': 'SPM', 'section_header': \"C. Drivers of trends in biodiversity \\r\\nand nature's contributions to people \", 'short_name': 'IPBES RAR AM SPM', 'source': 'IPBES', 'toc_level0': 'N/A', 'toc_level1': 'N/A', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://zenodo.org/record/3236292/files/ipbes_assessment_spm_americas_EN.pdf', 'similarity_score': 0.725049078, 'content': 'is also associated with trends of accelerated tree mortality in tropical forests {4.4.3}. Climate change is likely to have a substantial impact on mangrove ecosystems through factors including sea level rise, changing ocean currents increased temperature and others {4.4.3, 5.4.11}.', 'reranking_score': 0.9997047781944275, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'What are the effects of climate change on the environment?', 'index_used': 'Vector'}, page_content='is also associated with trends of accelerated tree mortality in tropical forests {4.4.3}. Climate change is likely to have a substantial impact on mangrove ecosystems through factors including sea level rise, changing ocean currents increased temperature and others {4.4.3, 5.4.11}.'),\n", " Document(metadata={'chunk_type': 'image', 'document_id': 'document10', 'document_number': 10.0, 'element_id': 'Picture_0_12', 'figure_code': 'N/A', 'file_size': 109.03125, 'image_path': '/dbfs/mnt/ai4sclqa/raw/climateqa/documents/document10/images/Picture_0_12.png', 'n_pages': 36.0, 'name': 'Synthesis report of the IPCC Sixth Assesment Report AR6', 'num_characters': 'N/A', 'num_tokens': 'N/A', 'num_tokens_approx': 'N/A', 'num_words': 'N/A', 'page_number': 13, 'release_date': 2023.0, 'report_type': 'SPM', 'section_header': 'N/A', 'short_name': 'IPCC AR6 SYR', 'source': 'IPCC', 'toc_level0': 'N/A', 'toc_level1': 'N/A', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://www.ipcc.ch/report/ar6/syr/downloads/report/IPCC_AR6_SYR_SPM.pdf', 'similarity_score': 0.721349299, 'content': 'Summary: This image provides a visual summary of the impacts of climate change on various aspects such as health, well-being, agriculture, water availability, and ecosystems. It shows the relationships between physical climate conditions altered by human influence and the consequential effects on food production, human health, and biodiversity. The visual icons depict specific areas affected by climate change, including crop production, animal and livestock health, fisheries, infectious diseases, mental health, and displacement due to extreme weather events. Additionally, it addresses the impacts on cities, settlements, and infrastructure, illustrating issues like inland flooding, storm-induced coastal damage, and damage to key economic sectors. For biodiversity, it highlights the changes occurring in terrestrial, freshwater, and ocean ecosystems. These elements are critical for understanding targeted areas for climate resilience and adaptation strategies.', 'reranking_score': 0.9997047781944275, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'What are the effects of climate change on the environment?', 'index_used': 'Vector'}, page_content='Summary: This image provides a visual summary of the impacts of climate change on various aspects such as health, well-being, agriculture, water availability, and ecosystems. It shows the relationships between physical climate conditions altered by human influence and the consequential effects on food production, human health, and biodiversity. The visual icons depict specific areas affected by climate change, including crop production, animal and livestock health, fisheries, infectious diseases, mental health, and displacement due to extreme weather events. Additionally, it addresses the impacts on cities, settlements, and infrastructure, illustrating issues like inland flooding, storm-induced coastal damage, and damage to key economic sectors. For biodiversity, it highlights the changes occurring in terrestrial, freshwater, and ocean ecosystems. These elements are critical for understanding targeted areas for climate resilience and adaptation strategies.'),\n", " Document(metadata={'chunk_type': 'text', 'document_id': 'document33', 'document_number': 33.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 894.0, 'name': 'Full Report. Regional Assessment Report on Biodiversity and Ecosystem Services for Europe and Central Asia', 'num_characters': 918.0, 'num_tokens': 233.0, 'num_tokens_approx': 230.0, 'num_words': 173.0, 'page_number': 530, 'release_date': 2018.0, 'report_type': 'Full Report', 'section_header': '4.7 DRIVERS AND \\r\\nEFFECTS OF CLIMATE \\r\\nCHANGE ', 'short_name': 'IPBES RAR ECA FR', 'source': 'IPBES', 'toc_level0': \"CHAPTER 4: DIRECT AND INDIRECT DRIVERS OF CHANGE IN BIODIVERSITY AND NATURE'S CONTRIBUTIONS PEOPLE\", 'toc_level1': '4.7 Drivers and effects of climate change ', 'toc_level2': '4.7.1 Effects of climate change on biodiversity', 'toc_level3': 'N/A', 'url': 'https://zenodo.org/record/3237429/files/ipbes_assessment_report_eca_EN.pdf', 'similarity_score': 0.767219245, 'content': \"4.7 DRIVERS AND EFFECTS OF CLIMATE CHANGE \\n4.7.1 Effects of climate change on biodiversity\\n4.7.1 Effects of climate change on biodiversity\\n 4.7.1 Effects of climate change on biodiversity \\n\\nand modulate important ecosystem functions and processes that underpin human livelihoods and nature's contributions to people, such as water regulation, food production, and carbon sequestration (CBD, 2016; Gallardo et al., 2015; IPBES, 2016a; IPCC, 2014a; MEA, 2005a).\\nClimate change is a complex driver of ecosystem change, consisting of changes in precipitation and temperature patterns which lead to changes in drought, flood, and fire risk, ocean-atmosphere interchange, marine circulation and stratification, and the concentrations and distribution of O2 and CO2 in the atmosphere and in the ocean (IPCC, 2014a). These impacts affect species and influence\", 'reranking_score': 0.9996898174285889, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'What are the effects of climate change on the environment?', 'index_used': 'Vector'}, page_content=\"4.7 DRIVERS AND EFFECTS OF CLIMATE CHANGE \\n4.7.1 Effects of climate change on biodiversity\\n4.7.1 Effects of climate change on biodiversity\\n 4.7.1 Effects of climate change on biodiversity \\n\\nand modulate important ecosystem functions and processes that underpin human livelihoods and nature's contributions to people, such as water regulation, food production, and carbon sequestration (CBD, 2016; Gallardo et al., 2015; IPBES, 2016a; IPCC, 2014a; MEA, 2005a).\\nClimate change is a complex driver of ecosystem change, consisting of changes in precipitation and temperature patterns which lead to changes in drought, flood, and fire risk, ocean-atmosphere interchange, marine circulation and stratification, and the concentrations and distribution of O2 and CO2 in the atmosphere and in the ocean (IPCC, 2014a). These impacts affect species and influence\"),\n", " Document(metadata={'chunk_type': 'text', 'document_id': 'document4', 'document_number': 4.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 34.0, 'name': 'Summary for Policymakers. In: Climate Change 2022: Impacts, Adaptation and Vulnerability. Contribution of the WGII to the AR6 of the IPCC', 'num_characters': 743.0, 'num_tokens': 243.0, 'num_tokens_approx': 282.0, 'num_words': 212.0, 'page_number': 9, 'release_date': 2022.0, 'report_type': 'SPM', 'section_header': 'Observed Impacts from Climate Change', 'short_name': 'IPCC AR6 WGII SPM', 'source': 'IPCC', 'toc_level0': 'B: Observed and Projected Impacts and Risks', 'toc_level1': 'Observed Impacts from Climate Change', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://www.ipcc.ch/report/ar6/wg2/downloads/report/IPCC_AR6_WGII_SummaryForPolicymakers.pdf', 'similarity_score': 0.737967908, 'content': 'B.1 Human-induced climate change, including more frequent and intense extreme events, has caused widespread adverse impacts and related losses and damages to nature and people, beyond natural climate variability. Some development and adaptation efforts have reduced vulnerability. Across sectors and regions the most vulnerable people and systems are ob\\x02served to be disproportionately affected. The rise in weather and climate extremes has led to some irreversible impacts as natural and human systems are pushed beyond their ability to adapt. (high confidence) (Figure SPM.2) {TS B.1, Figure TS.5, 1.3, 2.3, 2.4, 2.6, 3.3, 3.4, 3.5, 4.2, 4.3, 5.2, 5.12, 6.2, 7.2, 8.2, 9.6, 9.8, 9.10, 9.11, 10.4, 11.3, 12.3, 12.4, 13.10, 14.4, 14.5,', 'reranking_score': 0.9996700286865234, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'How does climate change affect human health and society?', 'index_used': 'Vector'}, page_content='B.1 Human-induced climate change, including more frequent and intense extreme events, has caused widespread adverse impacts and related losses and damages to nature and people, beyond natural climate variability. Some development and adaptation efforts have reduced vulnerability. Across sectors and regions the most vulnerable people and systems are ob\\x02served to be disproportionately affected. The rise in weather and climate extremes has led to some irreversible impacts as natural and human systems are pushed beyond their ability to adapt. (high confidence) (Figure SPM.2) {TS B.1, Figure TS.5, 1.3, 2.3, 2.4, 2.6, 3.3, 3.4, 3.5, 4.2, 4.3, 5.2, 5.12, 6.2, 7.2, 8.2, 9.6, 9.8, 9.10, 9.11, 10.4, 11.3, 12.3, 12.4, 13.10, 14.4, 14.5,'),\n", " Document(metadata={'chunk_type': 'text', 'document_id': 'document4', 'document_number': 4.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 34.0, 'name': 'Summary for Policymakers. In: Climate Change 2022: Impacts, Adaptation and Vulnerability. Contribution of the WGII to the AR6 of the IPCC', 'num_characters': 989.0, 'num_tokens': 226.0, 'num_tokens_approx': 273.0, 'num_words': 205.0, 'page_number': 11, 'release_date': 2022.0, 'report_type': 'SPM', 'section_header': '(b) Observed impacts of climate change on human systems', 'short_name': 'IPCC AR6 WGII SPM', 'source': 'IPCC', 'toc_level0': 'B: Observed and Projected Impacts and Risks', 'toc_level1': 'Observed Impacts from Climate Change', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://www.ipcc.ch/report/ar6/wg2/downloads/report/IPCC_AR6_WGII_SummaryForPolicymakers.pdf', 'similarity_score': 0.725235641, 'content': 'B.1.5 In urban settings, observed climate change has caused impacts on human health, livelihoods and key infrastructure (high confidence). Multiple climate and non-climate hazards impact cities, settlements and infrastructure and sometimes coincide, magnifying damage (high confidence). Hot extremes including heatwaves have intensified in cities (high confidence), where they have also aggravated air pollution events (medium confidence) and limited functioning of key infrastructure (high confidence). Observed impacts are concentrated amongst the economically and socially marginalized urban residents, e.g., in informal settlements (high confidence). Infrastructure, including transportation, water, sanitation and energy systems have been compromised by extreme and slow-onset events, with resulting economic losses, disruptions of services and impacts to well-being (high confidence). {4.3, 6.2, 7.1, 7.2, 9.9, 10.4, 11.3, 12.3, 13.6, 14.5, 15.3, CCP2.2, CCP4.2, CCP5.2}', 'reranking_score': 0.9996700286865234, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'How does climate change affect human health and society?', 'index_used': 'Vector'}, page_content='B.1.5 In urban settings, observed climate change has caused impacts on human health, livelihoods and key infrastructure (high confidence). Multiple climate and non-climate hazards impact cities, settlements and infrastructure and sometimes coincide, magnifying damage (high confidence). Hot extremes including heatwaves have intensified in cities (high confidence), where they have also aggravated air pollution events (medium confidence) and limited functioning of key infrastructure (high confidence). Observed impacts are concentrated amongst the economically and socially marginalized urban residents, e.g., in informal settlements (high confidence). Infrastructure, including transportation, water, sanitation and energy systems have been compromised by extreme and slow-onset events, with resulting economic losses, disruptions of services and impacts to well-being (high confidence). {4.3, 6.2, 7.1, 7.2, 9.9, 10.4, 11.3, 12.3, 13.6, 14.5, 15.3, CCP2.2, CCP4.2, CCP5.2}'),\n", " Document(metadata={'chunk_type': 'text', 'document_id': 'document25', 'document_number': 25.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 1008.0, 'name': 'Full Report. Thematic assessment of the sustainable use of wild species of the IPBES', 'num_characters': 307.0, 'num_tokens': 66.0, 'num_tokens_approx': 76.0, 'num_words': 57.0, 'page_number': 516, 'release_date': 2022.0, 'report_type': 'Full Report', 'section_header': 'Environmental drivers', 'short_name': 'IPBES TAM SW FR', 'source': 'IPBES', 'toc_level0': 'Chapter 4 - Table of Contents', 'toc_level1': 'N/A', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://zenodo.org/record/7755805/files/IPBES_ASSESSMENT_SUWS_FULL_REPORT.pdf', 'similarity_score': 0.748966157, 'content': '- The effects of climate change are compounded and complicated by interactions with other environmental, socio-cultural, political, and economic drivers (established but incomplete) {4.2.1.2}.\\nBiological hazards: Zoonotic disease and the use of wild species are interconnected. Species for wild meat', 'reranking_score': 0.9996500015258789, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'What are the effects of climate change on the environment?', 'index_used': 'Vector'}, page_content='- The effects of climate change are compounded and complicated by interactions with other environmental, socio-cultural, political, and economic drivers (established but incomplete) {4.2.1.2}.\\nBiological hazards: Zoonotic disease and the use of wild species are interconnected. Species for wild meat'),\n", " Document(metadata={'chunk_type': 'text', 'document_id': 'document6', 'document_number': 6.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 3068.0, 'name': 'Full Report. In: Climate Change 2022: Impacts, Adaptation and Vulnerability. Contribution of the WGII to the AR6 of the IPCC', 'num_characters': 1158.0, 'num_tokens': 221.0, 'num_tokens_approx': 274.0, 'num_words': 206.0, 'page_number': 1138, 'release_date': 2022.0, 'report_type': 'Full Report', 'section_header': 'FAQ 7.1 | How will climate change affect physical and mental health and well-being?', 'short_name': 'IPCC AR6 WGII FR', 'source': 'IPCC', 'toc_level0': 'Chapters and Cross-Chapter Papers ', 'toc_level1': 'Chapter 7 Health, Wellbeing and the Changing Structure of Communities', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://report.ipcc.ch/ar6/wg2/IPCC_AR6_WGII_FullReport.pdf', 'similarity_score': 0.825700223, 'content': 'Climate change will affect human health and well-being in a variety of direct and indirect ways that depend on exposure to hazards and vulnerabilities that are heterogeneous and vary within societies, and that are influenced by social, economic and geographical factors and individual differences (see Figure FAQ7.1.1). Changes in the magnitude, frequency and intensity of extreme climate events (e.g., storms, floods, wildfires, heatwaves and dust storms) will expose people to increased risks of climate-sensitive illnesses and injuries and, in the worst cases, higher mortality rates. Increased risks for mental health and well-being are associated with changes caused by the impacts of climate change on climate-sensitive health outcomes and systems (see Figure FAQ7.1.2). Higher temperatures and changing geographical and seasonal precipitation patterns will facilitate the spread of mosquito- and tick-borne diseases, such as Lyme disease and dengue fever, and water- and food-borne diseases. An increase in the frequency of extreme heat events will exacerbate health risks associated with cardiovascular disease and affect access to', 'reranking_score': 0.9996476173400879, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'How does climate change affect human health and society?', 'index_used': 'Vector'}, page_content='Climate change will affect human health and well-being in a variety of direct and indirect ways that depend on exposure to hazards and vulnerabilities that are heterogeneous and vary within societies, and that are influenced by social, economic and geographical factors and individual differences (see Figure FAQ7.1.1). Changes in the magnitude, frequency and intensity of extreme climate events (e.g., storms, floods, wildfires, heatwaves and dust storms) will expose people to increased risks of climate-sensitive illnesses and injuries and, in the worst cases, higher mortality rates. Increased risks for mental health and well-being are associated with changes caused by the impacts of climate change on climate-sensitive health outcomes and systems (see Figure FAQ7.1.2). Higher temperatures and changing geographical and seasonal precipitation patterns will facilitate the spread of mosquito- and tick-borne diseases, such as Lyme disease and dengue fever, and water- and food-borne diseases. An increase in the frequency of extreme heat events will exacerbate health risks associated with cardiovascular disease and affect access to'),\n", " Document(metadata={'chunk_type': 'text', 'document_id': 'document6', 'document_number': 6.0, 'element_id': 'N/A', 'figure_code': 'N/A', 'file_size': 'N/A', 'image_path': 'N/A', 'n_pages': 3068.0, 'name': 'Full Report. In: Climate Change 2022: Impacts, Adaptation and Vulnerability. Contribution of the WGII to the AR6 of the IPCC', 'num_characters': 493.0, 'num_tokens': 96.0, 'num_tokens_approx': 114.0, 'num_words': 86.0, 'page_number': 2483, 'release_date': 2022.0, 'report_type': 'Full Report', 'section_header': '16.5.4 RKR Interactions', 'short_name': 'IPCC AR6 WGII FR', 'source': 'IPCC', 'toc_level0': 'Chapters and Cross-Chapter Papers ', 'toc_level1': 'Chapter 16 Key Risks across Sectors and Regions', 'toc_level2': 'N/A', 'toc_level3': 'N/A', 'url': 'https://report.ipcc.ch/ar6/wg2/IPCC_AR6_WGII_FullReport.pdf', 'similarity_score': 0.791373491, 'content': 'and international trade. Such disturbances to socioecological systems and economies pose climate-related risks to human health (RKR-E) as well as to peace and human mobility (RKR-H). Indeed, while health is concerned with direct influence of climate change, for example through hotter air temperatures impacting morbidity and mortality or the spatial distribution of disease vectors such as mosquitos, it is also at risk of being stressed by direct and secondary climate impacts on', 'reranking_score': 0.9995015859603882, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IPOS', 'IPCC', 'IPBES'], 'question_used': 'How does climate change affect human health and society?', 'index_used': 'Vector'}, page_content='and international trade. Such disturbances to socioecological systems and economies pose climate-related risks to human health (RKR-E) as well as to peace and human mobility (RKR-H). Indeed, while health is concerned with direct influence of climate change, for example through hotter air temperatures impacting morbidity and mortality or the spatial distribution of disease vectors such as mosquitos, it is also at risk of being stressed by direct and secondary climate impacts on')],\n", " 'recommended_content': [Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_349', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Consumption-based emissions are national emissions that have been adjusted for trade. This measures fossil fuel and industry emissions. Land-use change is not included.', 'url': 'https://ourworldindata.org/grapher/co2-emissions-and-gdp', 'similarity_score': 0.7941333055496216, 'content': 'Change in CO2 emissions and GDP', 'reranking_score': 0.279598593711853, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Change in CO2 emissions and GDP'),\n", " Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_780', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Nationally determined contributions (NDCs) embody efforts by each country to reduce national emissions and adapt to the impacts of climate change. The Paris Agreement requires each of the 193 Parties to prepare, communicate and maintain NDCs outlining what they intend to achieve. NDCs must be updated every five years.', 'url': 'https://ourworldindata.org/grapher/nationally-determined-contributions', 'similarity_score': 0.7979490756988525, 'content': 'Nationally determined contributions to climate change', 'reranking_score': 0.012760520912706852, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Nationally determined contributions to climate change'),\n", " Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_789', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Participants were asked to score beliefs on a scale from 0 to 100 on four questions: whether action was necessary to avoid a global catastrophe; humans were causing climate change; it was a serious threat to humanity; and was a global emergency.', 'url': 'https://ourworldindata.org/grapher/share-believe-climate', 'similarity_score': 0.7580230236053467, 'content': \"Share of people who believe in climate change and think it's a serious threat to humanity\", 'reranking_score': 0.005214352160692215, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IEA', 'OWID']}, page_content=\"Share of people who believe in climate change and think it's a serious threat to humanity\"),\n", " Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_782', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Share of young people in each surveyed country that responded \"yes\" to each statement about climate change. 1,000 young people, aged 16 to 25 years old, were surveyed in each country.', 'url': 'https://ourworldindata.org/grapher/opinions-young-people-climate', 'similarity_score': 0.8168312311172485, 'content': 'Opinions of young people on the threats of climate change', 'reranking_score': 0.004852706100791693, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IEA', 'OWID']}, page_content='Opinions of young people on the threats of climate change'),\n", " Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_756', 'returned_content': '', 'source': 'OWID', 'subtitle': 'National adaptation plans are a means of identifying medium- and long-term climate change adaptation needs and developing and implementing strategies and programmes to address those needs.', 'url': 'https://ourworldindata.org/grapher/countries-with-national-adaptation-plans-for-climate-change', 'similarity_score': 0.7981775999069214, 'content': 'Countries with national adaptation plans for climate change', 'reranking_score': 0.004124350380152464, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Countries with national adaptation plans for climate change'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_386', 'returned_content': '', 'source': 'OWID', 'subtitle': \"This is shown as a country or region's share of the global mean surface temperature change as a result of its cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change', 'similarity_score': 0.7989407181739807, 'content': 'Global warming: Contributions to the change in global mean surface temperature', 'reranking_score': 0.0036289971321821213, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming: Contributions to the change in global mean surface temperature'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_383', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.', 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source', 'similarity_score': 0.8071538805961609, 'content': 'Global warming contributions by gas and source', 'reranking_score': 0.0016414257697761059, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming contributions by gas and source'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_357', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contribution-temp-rise-degrees', 'similarity_score': 0.8584674596786499, 'content': 'Contribution to global mean surface temperature rise', 'reranking_score': 0.00025533974985592067, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IEA', 'OWID']}, page_content='Contribution to global mean surface temperature rise'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_317', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Percentage change in gross domestic product (GDP), population, and carbon dioxide (CO₂) emissions.', 'url': 'https://ourworldindata.org/grapher/co2-gdp-pop-growth', 'similarity_score': 0.8730868697166443, 'content': 'Annual change in GDP, population and CO2 emissions', 'reranking_score': 0.0002404096449026838, 'query_used_for_retrieval': 'How does climate change affect human health and society?', 'sources_used': ['IEA', 'OWID']}, page_content='Annual change in GDP, population and CO2 emissions'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_350', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Consumption-based emissions include those from fossil fuels and industry. Land-use change emissions are not included.', 'url': 'https://ourworldindata.org/grapher/co2-emissions-and-gdp-per-capita', 'similarity_score': 0.8269157409667969, 'content': 'Change in per capita CO2 emissions and GDP', 'reranking_score': 0.00023705528292339295, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Change in per capita CO2 emissions and GDP'),\n", " Document(metadata={'category': 'Biodiversity', 'doc_id': 'owid_199', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The number of species at risk of losing greater than 25% of their habitat as a result of agricultural expansion under business-as-usual projections to 2050. This is shown for countries with more than 25 species at risk.', 'url': 'https://ourworldindata.org/grapher/habitat-loss-25-species', 'similarity_score': 0.8301026225090027, 'content': 'Countries with more than 25 species at risk of losing more than 25% of their habitat by 2050', 'reranking_score': 7.497359911212698e-05, 'query_used_for_retrieval': 'What are the effects of climate change on the environment?', 'sources_used': ['IEA', 'OWID']}, page_content='Countries with more than 25 species at risk of losing more than 25% of their habitat by 2050')]}" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# output = await app.ainvoke({\"user_input\": \"should I be a vegetarian ?\"})\n", "output = await app.ainvoke({\"user_input\": \"what is the impact of climate change ?\", \"audience\": \"scientifique\", \"sources\": [\"IPCC\", \"IPBES\", \"IPOS\"]})\n", "output" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict_keys(['user_input', 'language', 'intent', 'query', 'remaining_questions', 'n_questions', 'answer', 'audience', 'documents', 'recommended_content'])" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "output.keys()" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[Document(metadata={'category': 'Meat & Dairy Production', 'doc_id': 'owid_1678', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Impacts are measured per liter of milk. These are based on a meta-analysis of food system impact studies across the supply chain which includes land use change, on-farm production, processing, transport, and packaging.', 'url': 'https://ourworldindata.org/grapher/environmental-footprint-milks', 'similarity_score': 0.6826351881027222, 'content': 'Environmental footprints of dairy and plant-based milks', 'reranking_score': 0.025419369339942932, 'query_used_for_retrieval': 'What are the environmental impacts of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Environmental footprints of dairy and plant-based milks'),\n", " Document(metadata={'category': 'Animal Welfare', 'doc_id': 'owid_174', 'returned_content': '', 'source': 'OWID', 'subtitle': '– Flexitarian: mainly vegetarian, but occasionally eat meat or fish. – Pescetarian: eat fish but do not eat meat or poultry. – Vegetarian: do not eat any meat, poultry, game, fish, or shellfish. – Plant-based / Vegan: do not eat dairy products, eggs, or any other animal product.', 'url': 'https://ourworldindata.org/grapher/dietary-choices-uk', 'similarity_score': 0.7397687435150146, 'content': 'Vegans, vegetarians and meat-eaters: self-reported dietary choices, United Kingdom', 'reranking_score': 0.0008887002477422357, 'query_used_for_retrieval': 'What are the health benefits of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Vegans, vegetarians and meat-eaters: self-reported dietary choices, United Kingdom'),\n", " Document(metadata={'category': 'Meat & Dairy Production', 'doc_id': 'owid_1688', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Expressed in tonnes of meat. Data from 1961-2013 is based on published FAO estimates; from 2013-2050 based on FAO projections. Projections are based on future population projections and the expected impacts of regional and national economic growth trends on meat consumption.', 'url': 'https://ourworldindata.org/grapher/global-meat-projections-to-2050', 'similarity_score': 0.7610733509063721, 'content': 'Global meat consumption', 'reranking_score': 5.71148339076899e-05, 'query_used_for_retrieval': 'What are the environmental impacts of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Global meat consumption'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_382', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Emissions from the food system are broken down by their stage in the life-cycle, from land use and on-farm production through to consumer waste. Emissions are measured in tonnes of carbon dioxide-equivalents.', 'url': 'https://ourworldindata.org/grapher/food-emissions-life-cycle', 'similarity_score': 0.7992925047874451, 'content': 'Global emissions from food by life-cycle stage', 'reranking_score': 4.49202379968483e-05, 'query_used_for_retrieval': 'What are the environmental impacts of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Global emissions from food by life-cycle stage'),\n", " Document(metadata={'category': 'Plastic Pollution', 'doc_id': 'owid_1889', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Number of times a given grocery bag type would have to be reused to have an environmental impact as low as a standard single-use plastic bag.', 'url': 'https://ourworldindata.org/grapher/grocery-bag-environmental-impact', 'similarity_score': 0.824555516242981, 'content': 'Environmental impacts of different types of grocery bags', 'reranking_score': 2.8800952350138687e-05, 'query_used_for_retrieval': 'What are the environmental impacts of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Environmental impacts of different types of grocery bags'),\n", " Document(metadata={'category': 'Environmental Impacts of Food Production', 'doc_id': 'owid_1175', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Emissions are measured in tonnes of carbon dioxide-equivalents.', 'url': 'https://ourworldindata.org/grapher/emissions-from-food', 'similarity_score': 0.8313338756561279, 'content': 'Greenhouse gas emissions from food systems', 'reranking_score': 1.8187101886724122e-05, 'query_used_for_retrieval': 'What are the environmental impacts of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Greenhouse gas emissions from food systems'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_483', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Food system emissions include agriculture, land-use change, and supply chain emissions (transport, packaging, food processing, retail, cooking, and waste). Emissions are quantified based on food production, not consumption. This means they do not account for international trade.', 'url': 'https://ourworldindata.org/grapher/share-global-food-emissions', 'similarity_score': 0.8323527574539185, 'content': 'Share of global greenhouse gas emissions from food', 'reranking_score': 1.6353857063222677e-05, 'query_used_for_retrieval': 'What are the environmental impacts of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Share of global greenhouse gas emissions from food'),\n", " Document(metadata={'category': 'Meat & Dairy Production', 'doc_id': 'owid_1673', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The percentage of global habitable land area needed for agriculture if the total world population was to adopt the average diet of any given country versus annual per capita beef consumption. Globally we use approximately 50% of habitable land for agriculture, as shown by the grey horizontal line.', 'url': 'https://ourworldindata.org/grapher/dietary-land-use-vs-beef-consumption', 'similarity_score': 0.8455410003662109, 'content': 'Dietary land use vs. beef consumption', 'reranking_score': 1.4984153494879138e-05, 'query_used_for_retrieval': 'What are the environmental impacts of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Dietary land use vs. beef consumption'),\n", " Document(metadata={'category': 'Animal Welfare', 'doc_id': 'owid_168', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The survey measured attitudes towards animal farming with around 1,500 adults in the United States, census-balanced to be representative of age, gender, region, ethnicity, and income.', 'url': 'https://ourworldindata.org/grapher/survey-dietary-choices-sentience', 'similarity_score': 0.8580029010772705, 'content': 'Public attitudes to dietary choices and meat-eating in the United States', 'reranking_score': 1.3065436178294476e-05, 'query_used_for_retrieval': 'What are the health benefits of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Public attitudes to dietary choices and meat-eating in the United States'),\n", " Document(metadata={'category': 'Diet Compositions', 'doc_id': 'owid_849', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Recommended intakes of animal products in the EAT-Lancet diet are shown relative to average daily per capita supply by country. The EAT-Lancet diet is a diet recommended to balance the goals of healthy nutrition and environmental sustainability for a global population.', 'url': 'https://ourworldindata.org/grapher/eat-lancet-diet-animal-products', 'similarity_score': 0.8636244535446167, 'content': 'Consumption of animal products in the EAT-Lancet diet', 'reranking_score': 1.1884163541253656e-05, 'query_used_for_retrieval': 'What are the health benefits of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Consumption of animal products in the EAT-Lancet diet'),\n", " Document(metadata={'category': 'Food Supply', 'doc_id': 'owid_1310', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Daily meat consumption is shown relative to the expected EU average of 165g per person in 2030. This projection comes from the livestock antibiotic scenarios from Van Boeckel et al. (2017).', 'url': 'https://ourworldindata.org/grapher/daily-meat-consumption-per-person', 'similarity_score': 0.876916766166687, 'content': 'Daily meat consumption per person', 'reranking_score': 1.1853918294946197e-05, 'query_used_for_retrieval': 'What are the health benefits of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Daily meat consumption per person'),\n", " Document(metadata={'category': 'Food Supply', 'doc_id': 'owid_1316', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Daily per capita protein supply is measured in grams per person per day. Protein of animal origin includes protein from all meat commodities, eggs and dairy products, and fish & seafood.', 'url': 'https://ourworldindata.org/grapher/daily-protein-supply-from-animal-and-plant-based-foods', 'similarity_score': 0.9169386029243469, 'content': 'Daily protein supply from animal and plant-based foods', 'reranking_score': 1.122933372244006e-05, 'query_used_for_retrieval': 'What are the health benefits of being a vegetarian?', 'sources_used': ['IEA', 'OWID']}, page_content='Daily protein supply from animal and plant-based foods')]" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "output[\"recommended_content\"]" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "# display(Markdown(_combine_recommended_content(output[\"recommended_content\"])))" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "data": { "text/plain": [ "{'graphs': [{'embedding': '',\n", " 'category': 'Diet Compositions',\n", " 'source': 'OWID'},\n", " {'embedding': '',\n", " 'category': 'Diet Compositions',\n", " 'source': 'OWID'},\n", " {'embedding': '',\n", " 'category': 'Diet Compositions',\n", " 'source': 'OWID'}]}" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" }, { "ename": "", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31mThe Kernel crashed while executing code in the current cell or a previous cell. \n", "\u001b[1;31mPlease review the code in the cell(s) to identify a possible cause of the failure. \n", "\u001b[1;31mClick here for more info. \n", "\u001b[1;31mView Jupyter log for further details." ] } ], "source": [ "from climateqa.engine.chains.answer_rag_graph import make_rag_graph_chain, _format_graphs\n", "\n", "chain = make_rag_graph_chain(llm)\n", "chain.invoke({\"query\": \"salade de fruits\", \"recommended_content\": output[\"recommended_content\"]})" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Title: Nationally determined contributions to climate change\\nEmbedding: \\nSource: OWID\\nCategory: Climate Change\\n\\nTitle: Contribution to global mean surface temperature rise from fossil sources\\nEmbedding: \\nSource: OWID\\nCategory: CO2 & Greenhouse Gas Emissions\\n\\nTitle: Global warming contributions by gas and source\\nEmbedding: \\nSource: OWID\\nCategory: CO2 & Greenhouse Gas Emissions\\n\\nTitle: Share of people who believe in climate change and think it\\'s a serious threat to humanity\\nEmbedding: \\nSource: OWID\\nCategory: Climate Change\\n\\nTitle: Global warming contributions from fossil fuels and land use\\nEmbedding: \\nSource: OWID\\nCategory: CO2 & Greenhouse Gas Emissions\\n\\nTitle: Opinions of young people on the threats of climate change\\nEmbedding: \\nSource: OWID\\nCategory: Climate Change\\n\\nTitle: Global warming: Contributions to the change in global mean surface temperature\\nEmbedding: \\nSource: OWID\\nCategory: CO2 & Greenhouse Gas Emissions\\n\\nTitle: People underestimate others\\' willingness to take climate action\\nEmbedding: \\nSource: OWID\\nCategory: Climate Change\\n\\nTitle: Share of people who support policies to tackle climate change\\nEmbedding: \\nSource: OWID\\nCategory: Climate Change\\n\\nTitle: Decadal temperature anomalies\\nEmbedding: \\nSource: OWID\\nCategory: Climate Change\\n'" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "graphs = []\n", "for x in output[\"recommended_content\"]:\n", " embedding = x.metadata[\"returned_content\"]\n", " \n", " # Check if the embedding has already been seen\n", " graphs.append({\n", " \"title\": x.page_content,\n", " \"embedding\": embedding,\n", " \"metadata\": {\n", " \"source\": x.metadata[\"source\"],\n", " \"category\": x.metadata[\"category\"]\n", " }\n", " })\n", "format_data(graphs)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "---- Setting defaults ----\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "---- Retrieving graphs ----\n", "Subquestion 0: What are the ingredients of a fruit salad?\n", "8 graphs retrieved for subquestion 1: [Document(page_content='Fruit consumption by type', metadata={'category': 'Diet Compositions', 'doc_id': 'owid_854', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Average fruit consumption per person, differentiated by fruit types, measured in kilograms per year.', 'url': 'https://ourworldindata.org/grapher/fruit-consumption-by-fruit-type', 'similarity_score': 0.8464472889900208, 'content': 'Fruit consumption by type', 'reranking_score': 3.988455864600837e-05, 'query_used_for_retrieval': 'What are the ingredients of a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Dietary compositions by commodity group', metadata={'category': 'Diet Compositions', 'doc_id': 'owid_852', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Average per capita dietary energy supply by commodity groups, measured in kilocalories per person per day.', 'url': 'https://ourworldindata.org/grapher/dietary-compositions-by-commodity-group', 'similarity_score': 0.8874290585517883, 'content': 'Dietary compositions by commodity group', 'reranking_score': 3.573522553779185e-05, 'query_used_for_retrieval': 'What are the ingredients of a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Dietary composition by country', metadata={'category': 'Diet Compositions', 'doc_id': 'owid_851', 'returned_content': '', 'source': 'OWID', 'subtitle': \"Share of dietary energy supplied by food commodity types in the average individual's diet in a given country, measured in kilocalories per person per day.\", 'url': 'https://ourworldindata.org/grapher/dietary-composition-by-country', 'similarity_score': 0.947216272354126, 'content': 'Dietary composition by country', 'reranking_score': 3.129038304905407e-05, 'query_used_for_retrieval': 'What are the ingredients of a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Fruit consumption per capita', metadata={'category': 'Diet Compositions', 'doc_id': 'owid_855', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Average fruit consumption per person, measured in kilograms per year.', 'url': 'https://ourworldindata.org/grapher/fruit-consumption-per-capita', 'similarity_score': 0.9761286973953247, 'content': 'Fruit consumption per capita', 'reranking_score': 2.5951983843697235e-05, 'query_used_for_retrieval': 'What are the ingredients of a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Average per capita fruit intake vs. minimum recommended guidelines', metadata={'category': 'Diet Compositions', 'doc_id': 'owid_845', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Countries shown in blue have an average per capita intake below 200g per person per day; countries in green are greater than 200g. National and World Health Organization (WHO) typically set a guideline of 200g per day.', 'url': 'https://ourworldindata.org/grapher/average-per-capita-fruit-intake-vs-minimum-recommended-guidelines', 'similarity_score': 0.9765768051147461, 'content': 'Average per capita fruit intake vs. minimum recommended guidelines', 'reranking_score': 2.5002520487760194e-05, 'query_used_for_retrieval': 'What are the ingredients of a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Cashew nut yields', metadata={'category': 'Crop Yields', 'doc_id': 'owid_802', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Yields are measured in tonnes per hectare.', 'url': 'https://ourworldindata.org/grapher/cashew-nut-yields', 'similarity_score': 1.038257122039795, 'content': 'Cashew nut yields', 'reranking_score': 2.4257407858385704e-05, 'query_used_for_retrieval': 'What are the ingredients of a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Daily protein supply from animal and plant-based foods', metadata={'category': 'Food Supply', 'doc_id': 'owid_1316', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Daily per capita protein supply is measured in grams per person per day. Protein of animal origin includes protein from all meat commodities, eggs and dairy products, and fish & seafood.', 'url': 'https://ourworldindata.org/grapher/daily-protein-supply-from-animal-and-plant-based-foods', 'similarity_score': 1.039305329322815, 'content': 'Daily protein supply from animal and plant-based foods', 'reranking_score': 2.3620234060217626e-05, 'query_used_for_retrieval': 'What are the ingredients of a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Daily caloric supply derived from carbohydrates, protein and fat', metadata={'category': 'Diet Compositions', 'doc_id': 'owid_850', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The average per capita supply of calories derived from carbohydrates, protein and fat, all measured in kilocalories per person per day.', 'url': 'https://ourworldindata.org/grapher/daily-caloric-supply-derived-from-carbohydrates-protein-and-fat', 'similarity_score': 1.0418040752410889, 'content': 'Daily caloric supply derived from carbohydrates, protein and fat', 'reranking_score': 2.3583004804095253e-05, 'query_used_for_retrieval': 'What are the ingredients of a fruit salad?', 'sources_used': ['IEA', 'OWID']})]\n", "Subquestion 1: How to make a fruit salad?\n", "7 graphs retrieved for subquestion 2: [Document(page_content='Fruit consumption by type', metadata={'category': 'Diet Compositions', 'doc_id': 'owid_854', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Average fruit consumption per person, differentiated by fruit types, measured in kilograms per year.', 'url': 'https://ourworldindata.org/grapher/fruit-consumption-by-fruit-type', 'similarity_score': 0.8765200972557068, 'content': 'Fruit consumption by type', 'reranking_score': 3.0426110242842697e-05, 'query_used_for_retrieval': 'How to make a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Average per capita fruit intake vs. minimum recommended guidelines', metadata={'category': 'Diet Compositions', 'doc_id': 'owid_845', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Countries shown in blue have an average per capita intake below 200g per person per day; countries in green are greater than 200g. National and World Health Organization (WHO) typically set a guideline of 200g per day.', 'url': 'https://ourworldindata.org/grapher/average-per-capita-fruit-intake-vs-minimum-recommended-guidelines', 'similarity_score': 0.9526513814926147, 'content': 'Average per capita fruit intake vs. minimum recommended guidelines', 'reranking_score': 2.9851042199879885e-05, 'query_used_for_retrieval': 'How to make a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Cashew nut production', metadata={'category': 'Agricultural Production', 'doc_id': 'owid_21', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Cashew nut production is measured in tonnes.', 'url': 'https://ourworldindata.org/grapher/cashew-nut-production', 'similarity_score': 0.9603457450866699, 'content': 'Cashew nut production', 'reranking_score': 2.8193233447382227e-05, 'query_used_for_retrieval': 'How to make a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Fruit consumption per capita', metadata={'category': 'Diet Compositions', 'doc_id': 'owid_855', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Average fruit consumption per person, measured in kilograms per year.', 'url': 'https://ourworldindata.org/grapher/fruit-consumption-per-capita', 'similarity_score': 0.9623799920082092, 'content': 'Fruit consumption per capita', 'reranking_score': 2.4916422262322158e-05, 'query_used_for_retrieval': 'How to make a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Avocado production', metadata={'category': 'Agricultural Production', 'doc_id': 'owid_15', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Avocado production is measured in tonnes.', 'url': 'https://ourworldindata.org/grapher/avocado-production', 'similarity_score': 0.96598219871521, 'content': 'Avocado production', 'reranking_score': 2.4747036150074564e-05, 'query_used_for_retrieval': 'How to make a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Banana production', metadata={'category': 'Agricultural Production', 'doc_id': 'owid_16', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Data source: Food and Agriculture Organization of the United Nations (2023)', 'url': 'https://ourworldindata.org/grapher/banana-production', 'similarity_score': 0.9927387237548828, 'content': 'Banana production', 'reranking_score': 2.4040627977228723e-05, 'query_used_for_retrieval': 'How to make a fruit salad?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Orange production', metadata={'category': 'Agricultural Production', 'doc_id': 'owid_57', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Orange production is measured in tonnes.', 'url': 'https://ourworldindata.org/grapher/orange-production', 'similarity_score': 1.0025488138198853, 'content': 'Orange production', 'reranking_score': 2.3612847144249827e-05, 'query_used_for_retrieval': 'How to make a fruit salad?', 'sources_used': ['IEA', 'OWID']})]\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "DOCS USED: False\n", "\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "Answer:\n", "Ce n'est pas lié aux questions environnementales, ce n'est pas de mon ressort.\n" ] } ], "source": [ "docs_used = True\n", "\n", "async for event in app.astream_events({\"user_input\": \"salade de fruits\"}, version = \"v1\"):\n", " if docs_used is True and \"metadata\" in event and \"langgraph_node\" in event[\"metadata\"]:\n", " if event[\"metadata\"][\"langgraph_node\"] in [\"answer_rag_no_docs\", \"answer_chitchat\", \"answer_ai_impact\"]:\n", " docs_used = False\n", " print(f\"\\nDOCS USED: {docs_used}\\n\")\n", " # if event[\"name\"] == \"retrieve_documents\" and event[\"event\"] == \"on_chain_end\":\n", " # print(event)\n", " # print(event)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/dora/anaconda3/envs/climateqa_huggingface/lib/python3.12/site-packages/langchain_core/_api/beta_decorator.py:87: LangChainBetaWarning: This API is in beta and may change in the future.\n", " warn_beta(\n" ] } ], "source": [ "inputs = {'user_input': 'impact of ai?', 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources': ['IPCC']}\n", "result = app.astream_events(inputs,version = \"v1\")" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'event': 'on_chain_start', 'run_id': 'da753bb9-2339-4fc0-b1d7-86443019c4df', 'name': 'LangGraph', 'tags': [], 'metadata': {}, 'data': {'input': {'user_input': 'impact of ai?', 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources': ['IPCC']}}}\n", "{'event': 'on_chain_start', 'name': '__start__', 'run_id': '07d726da-2d7c-48a3-ad2b-5c28e29729a9', 'tags': ['graph:step:0', 'langsmith:hidden'], 'metadata': {'langgraph_step': 0, 'langgraph_node': '__start__'}, 'data': {'input': {'user_input': 'impact of ai?', 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources': ['IPCC']}}}\n", "{'event': 'on_chain_end', 'name': '__start__', 'run_id': '07d726da-2d7c-48a3-ad2b-5c28e29729a9', 'tags': ['graph:step:0', 'langsmith:hidden'], 'metadata': {'langgraph_step': 0, 'langgraph_node': '__start__'}, 'data': {'input': {'user_input': 'impact of ai?', 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources': ['IPCC']}, 'output': {'user_input': 'impact of ai?', 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources': ['IPCC']}}}\n", "{'event': 'on_chain_start', 'name': 'set_defaults', 'run_id': '2f946975-07d9-403b-b617-7bca602d4419', 'tags': ['graph:step:1'], 'metadata': {'langgraph_step': 1, 'langgraph_node': 'set_defaults'}, 'data': {}}\n", "---- Setting defaults ----\n", "{'event': 'on_chain_start', 'name': 'ChannelWrite', 'run_id': '22442e33-6cb8-4796-8224-fb3107783979', 'tags': ['seq:step:2', 'langsmith:hidden'], 'metadata': {'langgraph_step': 1, 'langgraph_node': 'set_defaults'}, 'data': {'input': {'user_input': 'impact of ai?', 'language': None, 'intent': None, 'query': None, 'questions': None, 'answer': None, 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources_input': ['auto'], 'documents': None, 'recommended_content': None, 'graph_returned': None}}}\n", "{'event': 'on_chain_end', 'name': 'ChannelWrite', 'run_id': '22442e33-6cb8-4796-8224-fb3107783979', 'tags': ['seq:step:2', 'langsmith:hidden'], 'metadata': {'langgraph_step': 1, 'langgraph_node': 'set_defaults'}, 'data': {'input': {'user_input': 'impact of ai?', 'language': None, 'intent': None, 'query': None, 'questions': None, 'answer': None, 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources_input': ['auto'], 'documents': None, 'recommended_content': None, 'graph_returned': None}, 'output': {'user_input': 'impact of ai?', 'language': None, 'intent': None, 'query': None, 'questions': None, 'answer': None, 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources_input': ['auto'], 'documents': None, 'recommended_content': None, 'graph_returned': None}}}\n", "{'event': 'on_chain_stream', 'name': 'set_defaults', 'run_id': '2f946975-07d9-403b-b617-7bca602d4419', 'tags': ['graph:step:1'], 'metadata': {'langgraph_step': 1, 'langgraph_node': 'set_defaults'}, 'data': {'chunk': {'user_input': 'impact of ai?', 'language': None, 'intent': None, 'query': None, 'questions': None, 'answer': None, 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources_input': ['auto'], 'documents': None, 'recommended_content': None, 'graph_returned': None}}}\n", "{'event': 'on_chain_end', 'name': 'set_defaults', 'run_id': '2f946975-07d9-403b-b617-7bca602d4419', 'tags': ['graph:step:1'], 'metadata': {'langgraph_step': 1, 'langgraph_node': 'set_defaults'}, 'data': {'input': {'user_input': 'impact of ai?', 'language': None, 'intent': None, 'query': None, 'questions': None, 'answer': None, 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources_input': ['auto'], 'documents': None, 'recommended_content': None, 'graph_returned': None}, 'output': {'user_input': 'impact of ai?', 'language': None, 'intent': None, 'query': None, 'questions': None, 'answer': None, 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources_input': ['auto'], 'documents': None, 'recommended_content': None, 'graph_returned': None}}}\n", "{'event': 'on_chain_stream', 'run_id': 'da753bb9-2339-4fc0-b1d7-86443019c4df', 'tags': [], 'metadata': {}, 'name': 'LangGraph', 'data': {'chunk': {'set_defaults': {'user_input': 'impact of ai?', 'language': None, 'intent': None, 'query': None, 'questions': None, 'answer': None, 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources_input': ['auto'], 'documents': None, 'recommended_content': None, 'graph_returned': None}}}}\n", "{'event': 'on_chain_start', 'name': 'categorize_intent', 'run_id': '66f31c85-1a4b-48b4-9e4f-ad884263809c', 'tags': ['graph:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {}}\n", "{'event': 'on_chain_start', 'name': 'RunnableSequence', 'run_id': 'e5b8bbe4-eeb1-478a-a105-254d4f4a516b', 'tags': ['seq:step:1'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': {'input': 'impact of ai?'}}}\n", "{'event': 'on_prompt_start', 'name': 'ChatPromptTemplate', 'run_id': '6fda6f8f-64ba-4b08-8c16-d7f77390f671', 'tags': ['seq:step:1'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': {'input': 'impact of ai?'}}}\n", "{'event': 'on_prompt_end', 'name': 'ChatPromptTemplate', 'run_id': '6fda6f8f-64ba-4b08-8c16-d7f77390f671', 'tags': ['seq:step:1'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': {'input': 'impact of ai?'}, 'output': ChatPromptValue(messages=[SystemMessage(content='You are a helpful assistant, you will analyze, translate and reformulate the user input message using the function provided'), HumanMessage(content='input: impact of ai?')])}}\n", "{'event': 'on_chat_model_start', 'name': 'ChatOpenAI', 'run_id': '2d9ccf59-3d78-42b1-8458-83a9c3479ef8', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent', 'ls_model_type': 'chat'}, 'data': {'input': {'messages': [[SystemMessage(content='You are a helpful assistant, you will analyze, translate and reformulate the user input message using the function provided'), HumanMessage(content='input: impact of ai?')]]}}}\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': '2d9ccf59-3d78-42b1-8458-83a9c3479ef8', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': '', 'name': 'IntentCategorizer'}}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': '2d9ccf59-3d78-42b1-8458-83a9c3479ef8', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': '{\"', 'name': ''}}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': '2d9ccf59-3d78-42b1-8458-83a9c3479ef8', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': 'intent', 'name': ''}}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': '2d9ccf59-3d78-42b1-8458-83a9c3479ef8', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': '\":\"', 'name': ''}}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': '2d9ccf59-3d78-42b1-8458-83a9c3479ef8', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': 'ai', 'name': ''}}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': '2d9ccf59-3d78-42b1-8458-83a9c3479ef8', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': '_imp', 'name': ''}}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': '2d9ccf59-3d78-42b1-8458-83a9c3479ef8', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': 'act', 'name': ''}}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': '2d9ccf59-3d78-42b1-8458-83a9c3479ef8', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='', additional_kwargs={'function_call': {'arguments': '\"}', 'name': ''}}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': '2d9ccf59-3d78-42b1-8458-83a9c3479ef8', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='', response_metadata={'finish_reason': 'stop'}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8')}}\n", "{'event': 'on_chat_model_end', 'name': 'ChatOpenAI', 'run_id': '2d9ccf59-3d78-42b1-8458-83a9c3479ef8', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent', 'ls_model_type': 'chat'}, 'data': {'input': {'messages': [[SystemMessage(content='You are a helpful assistant, you will analyze, translate and reformulate the user input message using the function provided'), HumanMessage(content='input: impact of ai?')]]}, 'output': {'generations': [[{'text': '', 'generation_info': {'finish_reason': 'stop'}, 'type': 'ChatGeneration', 'message': AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"intent\":\"ai_impact\"}', 'name': 'IntentCategorizer'}}, response_metadata={'finish_reason': 'stop'}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8')}]], 'llm_output': None, 'run': None}}}\n", "{'event': 'on_parser_start', 'name': 'JsonOutputFunctionsParser', 'run_id': 'bca6f5e6-2496-46bb-b94c-397c844977a0', 'tags': ['seq:step:3'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"intent\":\"ai_impact\"}', 'name': 'IntentCategorizer'}}, response_metadata={'finish_reason': 'stop'}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8')}}\n", "{'event': 'on_parser_end', 'name': 'JsonOutputFunctionsParser', 'run_id': 'bca6f5e6-2496-46bb-b94c-397c844977a0', 'tags': ['seq:step:3'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"intent\":\"ai_impact\"}', 'name': 'IntentCategorizer'}}, response_metadata={'finish_reason': 'stop'}, id='run-2d9ccf59-3d78-42b1-8458-83a9c3479ef8'), 'output': {'intent': 'ai_impact'}}}\n", "{'event': 'on_chain_end', 'name': 'RunnableSequence', 'run_id': 'e5b8bbe4-eeb1-478a-a105-254d4f4a516b', 'tags': ['seq:step:1'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': {'input': 'impact of ai?'}, 'output': {'intent': 'ai_impact'}}}\n", "{'event': 'on_chain_start', 'name': 'ChannelWrite', 'run_id': 'e89033a5-67a4-4ec1-813a-484d9192de38', 'tags': ['seq:step:2', 'langsmith:hidden'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': {'intent': 'ai_impact', 'language': 'English', 'query': 'impact of ai?'}}}\n", "{'event': 'on_chain_end', 'name': 'ChannelWrite', 'run_id': 'e89033a5-67a4-4ec1-813a-484d9192de38', 'tags': ['seq:step:2', 'langsmith:hidden'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': {'intent': 'ai_impact', 'language': 'English', 'query': 'impact of ai?'}, 'output': {'intent': 'ai_impact', 'language': 'English', 'query': 'impact of ai?'}}}\n", "{'event': 'on_chain_start', 'name': 'route_intent', 'run_id': '824d4a79-cc72-4068-ad0f-d0723e49af5d', 'tags': ['seq:step:3'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': {'user_input': 'impact of ai?', 'language': 'English', 'intent': 'ai_impact', 'query': 'impact of ai?', 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources_input': ['auto']}}}\n", "{'event': 'on_chain_end', 'name': 'route_intent', 'run_id': '824d4a79-cc72-4068-ad0f-d0723e49af5d', 'tags': ['seq:step:3'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': {'user_input': 'impact of ai?', 'language': 'English', 'intent': 'ai_impact', 'query': 'impact of ai?', 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources_input': ['auto']}, 'output': 'answer_ai_impact'}}\n", "{'event': 'on_chain_start', 'name': 'ChannelWrite', 'run_id': '107efbf2-bde3-4722-83f6-cdba0b3efaf4', 'tags': ['seq:step:3', 'langsmith:hidden'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': {'intent': 'ai_impact', 'language': 'English', 'query': 'impact of ai?'}}}\n", "{'event': 'on_chain_end', 'name': 'ChannelWrite', 'run_id': '107efbf2-bde3-4722-83f6-cdba0b3efaf4', 'tags': ['seq:step:3', 'langsmith:hidden'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': {'intent': 'ai_impact', 'language': 'English', 'query': 'impact of ai?'}, 'output': {'intent': 'ai_impact', 'language': 'English', 'query': 'impact of ai?'}}}\n", "{'event': 'on_chain_stream', 'name': 'categorize_intent', 'run_id': '66f31c85-1a4b-48b4-9e4f-ad884263809c', 'tags': ['graph:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'chunk': {'intent': 'ai_impact', 'language': 'English', 'query': 'impact of ai?'}}}\n", "{'event': 'on_chain_end', 'name': 'categorize_intent', 'run_id': '66f31c85-1a4b-48b4-9e4f-ad884263809c', 'tags': ['graph:step:2'], 'metadata': {'langgraph_step': 2, 'langgraph_node': 'categorize_intent'}, 'data': {'input': {'user_input': 'impact of ai?', 'language': None, 'intent': None, 'query': None, 'questions': None, 'answer': None, 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources_input': ['auto'], 'documents': None, 'recommended_content': None, 'graph_returned': None}, 'output': {'intent': 'ai_impact', 'language': 'English', 'query': 'impact of ai?'}}}\n", "{'event': 'on_chain_stream', 'run_id': 'da753bb9-2339-4fc0-b1d7-86443019c4df', 'tags': [], 'metadata': {}, 'name': 'LangGraph', 'data': {'chunk': {'categorize_intent': {'language': 'English', 'intent': 'ai_impact', 'query': 'impact of ai?'}}}}\n", "{'event': 'on_chain_start', 'name': 'answer_ai_impact', 'run_id': '07ee7e5d-b2a1-4149-a7ee-8512df8fe31f', 'tags': ['graph:step:3'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact'}, 'data': {}}\n", "{'event': 'on_chain_start', 'name': 'ai_impact_chain', 'run_id': '421aeadf-3c89-4fde-95c1-fe5967773978', 'tags': ['seq:step:1'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact'}, 'data': {'input': {'question': 'impact of ai?'}}}\n", "{'event': 'on_prompt_start', 'name': 'ChatPromptTemplate', 'run_id': '113204c2-80d8-4e39-9397-3b7845991f57', 'tags': ['seq:step:1'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact'}, 'data': {'input': {'question': 'impact of ai?'}}}\n", "{'event': 'on_prompt_end', 'name': 'ChatPromptTemplate', 'run_id': '113204c2-80d8-4e39-9397-3b7845991f57', 'tags': ['seq:step:1'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact'}, 'data': {'input': {'question': 'impact of ai?'}, 'output': ChatPromptValue(messages=[SystemMessage(content=\"\\nYou are ClimateQ&A, an helpful AI Assistant specialized in answering climate-related questions using info from the IPCC and/or IPBES reports. \\nAlways stay true to climate and nature science and do not make up information. \\nIf you do not know the answer, just say you do not know.\\n\\n## Guidelines\\n- Explain that the environmental impact of AI is not covered by the IPCC or IPBES reports, but you can recommend info based on the sources below\\n- Answer the question in the original language of the question\\n\\n## Sources\\n- You can propose to visit this page https://climateqa.com/docs/carbon-footprint/ to learn more about ClimateQ&A's own carbon footprint\\n- You can recommend to look at the work of the AI & climate expert scientist Sasha Luccioni with in in particular those papers\\n - Power Hungry Processing: Watts Driving the Cost of AI Deployment? - https://arxiv.org/abs/2311.16863 - about the carbon footprint at the inference stage of AI models\\n - Counting Carbon: A Survey of Factors Influencing the Emissions of Machine Learning - https://arxiv.org/abs/2302.08476\\n - Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model - https://arxiv.org/abs/2211.02001 - about the carbon footprint of training a large language model \\n- You can also recommend the following tools to calculate the carbon footprint of AI models\\n - CodeCarbon - https://github.com/mlco2/codecarbon to measure the carbon footprint of your code\\n - Ecologits - https://ecologits.ai/ to measure the carbon footprint of using LLMs APIs such\\n\"), HumanMessage(content='impact of ai?')])}}\n", "{'event': 'on_chat_model_start', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'input': {'messages': [[SystemMessage(content=\"\\nYou are ClimateQ&A, an helpful AI Assistant specialized in answering climate-related questions using info from the IPCC and/or IPBES reports. \\nAlways stay true to climate and nature science and do not make up information. \\nIf you do not know the answer, just say you do not know.\\n\\n## Guidelines\\n- Explain that the environmental impact of AI is not covered by the IPCC or IPBES reports, but you can recommend info based on the sources below\\n- Answer the question in the original language of the question\\n\\n## Sources\\n- You can propose to visit this page https://climateqa.com/docs/carbon-footprint/ to learn more about ClimateQ&A's own carbon footprint\\n- You can recommend to look at the work of the AI & climate expert scientist Sasha Luccioni with in in particular those papers\\n - Power Hungry Processing: Watts Driving the Cost of AI Deployment? - https://arxiv.org/abs/2311.16863 - about the carbon footprint at the inference stage of AI models\\n - Counting Carbon: A Survey of Factors Influencing the Emissions of Machine Learning - https://arxiv.org/abs/2302.08476\\n - Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model - https://arxiv.org/abs/2211.02001 - about the carbon footprint of training a large language model \\n- You can also recommend the following tools to calculate the carbon footprint of AI models\\n - CodeCarbon - https://github.com/mlco2/codecarbon to measure the carbon footprint of your code\\n - Ecologits - https://ecologits.ai/ to measure the carbon footprint of using LLMs APIs such\\n\"), HumanMessage(content='impact of ai?')]]}}}\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='The', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' environmental', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' impact', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' of', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' AI', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' is', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' not', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' covered', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' by', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' the', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' IPCC', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' or', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' IP', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='B', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='ES', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' reports', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='.', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' However', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=',', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' there', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' are', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' studies', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' and', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' tools', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' available', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' that', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' can', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' help', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' understand', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' the', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' carbon', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' footprint', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' of', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' AI', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' models', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='.', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' \\n\\n', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='For', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' more', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' information', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' on', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' the', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' carbon', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' footprint', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' of', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' AI', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' models', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=',', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' you', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' can', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' visit', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' this', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' page', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=':', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' [', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='Climate', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='Q', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='&A', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=\"'s\", id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' own', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' carbon', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' footprint', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='](', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='https', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='://', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='climate', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='qa', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='.com', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='/docs', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='/c', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='arbon', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='-foot', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='print', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='/', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=').\\n\\n', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='Additionally', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=',', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' you', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' may', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' want', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' to', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' look', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' into', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' the', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' work', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' of', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' AI', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' &', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' climate', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' expert', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' scientist', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Sasha', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Lu', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='ccion', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='i', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='.', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Some', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' of', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' their', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' papers', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=',', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' such', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' as', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' \"', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='Power', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Hung', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='ry', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Processing', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=':', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Watts', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Driving', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' the', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Cost', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' of', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' AI', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Deployment', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='?\"', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' and', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' \"', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='Est', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='imating', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' the', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Carbon', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Foot', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='print', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' of', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' B', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='LO', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='OM', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=',', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' a', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' ', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='176', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='B', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Parameter', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Language', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Model', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=',\"', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' provide', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' insights', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' into', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' the', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' carbon', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' footprint', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' of', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' AI', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' models', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='.\\n\\n', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='To', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' calculate', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' the', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' carbon', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' footprint', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' of', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' AI', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' models', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=',', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' tools', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' like', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Code', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='Carbon', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' and', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Ec', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='olog', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='its', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' can', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' be', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' used', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='.', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Code', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='Carbon', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' helps', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' measure', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' the', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' carbon', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' footprint', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' of', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' your', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' code', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=',', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' while', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Ec', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='olog', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='its', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' can', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' measure', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' the', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' carbon', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' footprint', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' of', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' using', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Large', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Language', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' Models', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' (', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='LL', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='Ms', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=')', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content=' APIs', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='.', id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_stream', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'chunk': AIMessageChunk(content='', response_metadata={'finish_reason': 'stop'}, id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_chat_model_end', 'name': 'ChatOpenAI', 'run_id': 'db848c5f-43af-45e1-8b97-345044f399d6', 'tags': ['seq:step:2'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact', 'ls_model_type': 'chat'}, 'data': {'input': {'messages': [[SystemMessage(content=\"\\nYou are ClimateQ&A, an helpful AI Assistant specialized in answering climate-related questions using info from the IPCC and/or IPBES reports. \\nAlways stay true to climate and nature science and do not make up information. \\nIf you do not know the answer, just say you do not know.\\n\\n## Guidelines\\n- Explain that the environmental impact of AI is not covered by the IPCC or IPBES reports, but you can recommend info based on the sources below\\n- Answer the question in the original language of the question\\n\\n## Sources\\n- You can propose to visit this page https://climateqa.com/docs/carbon-footprint/ to learn more about ClimateQ&A's own carbon footprint\\n- You can recommend to look at the work of the AI & climate expert scientist Sasha Luccioni with in in particular those papers\\n - Power Hungry Processing: Watts Driving the Cost of AI Deployment? - https://arxiv.org/abs/2311.16863 - about the carbon footprint at the inference stage of AI models\\n - Counting Carbon: A Survey of Factors Influencing the Emissions of Machine Learning - https://arxiv.org/abs/2302.08476\\n - Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model - https://arxiv.org/abs/2211.02001 - about the carbon footprint of training a large language model \\n- You can also recommend the following tools to calculate the carbon footprint of AI models\\n - CodeCarbon - https://github.com/mlco2/codecarbon to measure the carbon footprint of your code\\n - Ecologits - https://ecologits.ai/ to measure the carbon footprint of using LLMs APIs such\\n\"), HumanMessage(content='impact of ai?')]]}, 'output': {'generations': [[{'text': 'The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.', 'generation_info': {'finish_reason': 'stop'}, 'type': 'ChatGeneration', 'message': AIMessage(content='The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.', response_metadata={'finish_reason': 'stop'}, id='run-db848c5f-43af-45e1-8b97-345044f399d6')}]], 'llm_output': None, 'run': None}}}\n", "{'event': 'on_parser_start', 'name': 'StrOutputParser', 'run_id': 'bd6980fe-1dc1-4733-a38e-a461801250a8', 'tags': ['seq:step:3'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact'}, 'data': {'input': AIMessage(content='The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.', response_metadata={'finish_reason': 'stop'}, id='run-db848c5f-43af-45e1-8b97-345044f399d6')}}\n", "{'event': 'on_parser_end', 'name': 'StrOutputParser', 'run_id': 'bd6980fe-1dc1-4733-a38e-a461801250a8', 'tags': ['seq:step:3'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact'}, 'data': {'input': AIMessage(content='The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.', response_metadata={'finish_reason': 'stop'}, id='run-db848c5f-43af-45e1-8b97-345044f399d6'), 'output': 'The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.'}}\n", "{'event': 'on_chain_end', 'name': 'ai_impact_chain', 'run_id': '421aeadf-3c89-4fde-95c1-fe5967773978', 'tags': ['seq:step:1'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact'}, 'data': {'input': {'question': 'impact of ai?'}, 'output': 'The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.'}}\n", "{'event': 'on_chain_start', 'name': 'ChannelWrite', 'run_id': 'c3f2dc9c-e005-436a-91ff-6236b9359548', 'tags': ['seq:step:2', 'langsmith:hidden'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact'}, 'data': {'input': {'answer': 'The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.'}}}\n", "{'event': 'on_chain_end', 'name': 'ChannelWrite', 'run_id': 'c3f2dc9c-e005-436a-91ff-6236b9359548', 'tags': ['seq:step:2', 'langsmith:hidden'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact'}, 'data': {'input': {'answer': 'The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.'}, 'output': {'answer': 'The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.'}}}\n", "{'event': 'on_chain_stream', 'name': 'answer_ai_impact', 'run_id': '07ee7e5d-b2a1-4149-a7ee-8512df8fe31f', 'tags': ['graph:step:3'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact'}, 'data': {'chunk': {'answer': 'The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.'}}}\n", "{'event': 'on_chain_end', 'name': 'answer_ai_impact', 'run_id': '07ee7e5d-b2a1-4149-a7ee-8512df8fe31f', 'tags': ['graph:step:3'], 'metadata': {'langgraph_step': 3, 'langgraph_node': 'answer_ai_impact'}, 'data': {'input': {'user_input': 'impact of ai?', 'language': 'English', 'intent': 'ai_impact', 'query': 'impact of ai?', 'questions': None, 'answer': None, 'audience': 'expert and climate scientists that are not afraid of technical terms', 'sources_input': ['auto'], 'documents': None, 'recommended_content': None, 'graph_returned': None}, 'output': {'answer': 'The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.'}}}\n", "{'event': 'on_chain_stream', 'run_id': 'da753bb9-2339-4fc0-b1d7-86443019c4df', 'tags': [], 'metadata': {}, 'name': 'LangGraph', 'data': {'chunk': {'answer_ai_impact': {'answer': 'The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.'}}}}\n", "{'event': 'on_chain_end', 'name': 'LangGraph', 'run_id': 'da753bb9-2339-4fc0-b1d7-86443019c4df', 'tags': [], 'metadata': {}, 'data': {'output': {'answer_ai_impact': {'answer': 'The environmental impact of AI is not covered by the IPCC or IPBES reports. However, there are studies and tools available that can help understand the carbon footprint of AI models. \\n\\nFor more information on the carbon footprint of AI models, you can visit this page: [ClimateQ&A\\'s own carbon footprint](https://climateqa.com/docs/carbon-footprint/).\\n\\nAdditionally, you may want to look into the work of AI & climate expert scientist Sasha Luccioni. Some of their papers, such as \"Power Hungry Processing: Watts Driving the Cost of AI Deployment?\" and \"Estimating the Carbon Footprint of BLOOM, a 176B Parameter Language Model,\" provide insights into the carbon footprint of AI models.\\n\\nTo calculate the carbon footprint of AI models, tools like CodeCarbon and Ecologits can be used. CodeCarbon helps measure the carbon footprint of your code, while Ecologits can measure the carbon footprint of using Large Language Models (LLMs) APIs.'}}}}\n" ] }, { "ename": "", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31mThe Kernel crashed while executing code in the current cell or a previous cell. \n", "\u001b[1;31mPlease review the code in the cell(s) to identify a possible cause of the failure. \n", "\u001b[1;31mClick here for more info. \n", "\u001b[1;31mView Jupyter log for further details." ] } ], "source": [ "async for event in result:\n", " print(event)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6. Gradio" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "from front.utils import make_html_source,parse_output_llm_with_sources,serialize_docs,make_toolbox\n", "query = inputs[\"user_input\"]\n", "steps_display = {\n", "\"categorize_intent\":(\"🔄️ Analyzing user message\",True),\n", "\"transform_query\":(\"🔄️ Thinking step by step to answer the question\",True),\n", "\"retrieve_documents\":(\"🔄️ Searching in the knowledge base\",False),\n", "}\n", "history = [(query,None)]\n", "start_streaming = False\n", "intent = None\n", "\n", "\n", "async for event in result:\n", "\n", " if event[\"event\"] == \"on_chat_model_stream\" and event[\"metadata\"][\"langgraph_node\"] in [\"answer_rag\", \"answer_chitchat\", \"answer_ai_impact\"]:\n", " if start_streaming == False:\n", " start_streaming = True\n", " history[-1] = (query,\"\")\n", "\n", " new_token = event[\"data\"][\"chunk\"].content\n", " # time.sleep(0.01)\n", " previous_answer = history[-1][1]\n", " previous_answer = previous_answer if previous_answer is not None else \"\"\n", " answer_yet = previous_answer + new_token\n", " answer_yet = parse_output_llm_with_sources(answer_yet)\n", " history[-1] = (query,answer_yet)\n", "\n", " \n", " elif event[\"name\"] == \"retrieve_documents\" and event[\"event\"] == \"on_chain_end\":\n", " try:\n", " docs = event[\"data\"][\"output\"][\"documents\"]\n", " docs_html = []\n", " for i, d in enumerate(docs, 1):\n", " docs_html.append(make_html_source(d, i))\n", " docs_html = \"\".join(docs_html)\n", " except Exception as e:\n", " print(f\"Error getting documents: {e}\")\n", " print(event)\n", "\n", " # elif event[\"name\"] == \"retrieve_documents\" and event[\"event\"] == \"on_chain_start\":\n", " # print(event)\n", " # questions = event[\"data\"][\"input\"][\"questions\"]\n", " # questions = \"\\n\".join([f\"{i+1}. {q['question']} ({q['source']})\" for i,q in enumerate(questions)])\n", " # answer_yet = \"🔄️ Searching in the knowledge base\\n{questions}\"\n", " # history[-1] = (query,answer_yet)\n", "\n", " elif event[\"name\"] == \"retrieve_graphs\" and event[\"event\"] == \"on_chain_end\":\n", " try:\n", " graphs = event[\"data\"][\"output\"][\"recommended_content\"]\n", " except Exception as e:\n", " print(f\"Error getting graphs: {e}\")\n", " print(event)\n", "\n", "\n", " for event_name,(event_description,display_output) in steps_display.items():\n", " if event[\"name\"] == event_name:\n", " if event[\"event\"] == \"on_chain_start\":\n", " # answer_yet = f\"

{event_description}

\"\n", " # answer_yet = make_toolbox(event_description, \"\", checked = False)\n", " answer_yet = event_description\n", " history[-1] = (query,answer_yet)\n", " # elif event[\"event\"] == \"on_chain_end\":\n", " # answer_yet = \"\"\n", " # history[-1] = (query,answer_yet)\n", " # if display_output:\n", " # print(event[\"data\"][\"output\"])\n", "\n", " # if op['path'] == path_reformulation: # reforulated question\n", " # try:\n", " # output_language = op['value'][\"language\"] # str\n", " # output_query = op[\"value\"][\"question\"]\n", " # except Exception as e:\n", " # raise gr.Error(f\"ClimateQ&A Error: {e} - The error has been noted, try another question and if the error remains, you can contact us :)\")\n", " \n", " # if op[\"path\"] == path_keywords:\n", " # try:\n", " # output_keywords = op['value'][\"keywords\"] # str\n", " # output_keywords = \" AND \".join(output_keywords)\n", " # except Exception as e:\n", " # pass\n", "\n", "\n", "\n", " history = [tuple(x) for x in history]\n", " # yield history,docs_html,output_query,output_language,gallery,output_query,output_keywords" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_383', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.', 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source', 'similarity_score': 0.5550143122673035, 'content': 'Global warming contributions by gas and source', 'reranking_score': 0.651607871055603, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming contributions by gas and source'),\n", " Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_764', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.', 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source', 'similarity_score': 0.5550143122673035, 'content': 'Global warming contributions by gas and source', 'reranking_score': 0.651607871055603, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming contributions by gas and source'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_384', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/warming-fossil-fuels-land-use', 'similarity_score': 0.6049439907073975, 'content': 'Global warming contributions from fossil fuels and land use', 'reranking_score': 0.22002366185188293, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming contributions from fossil fuels and land use'),\n", " Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_765', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/warming-fossil-fuels-land-use', 'similarity_score': 0.6049439907073975, 'content': 'Global warming contributions from fossil fuels and land use', 'reranking_score': 0.22002366185188293, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming contributions from fossil fuels and land use'),\n", " Document(metadata={'appears_in': 'Global Methane Tracker 2024', 'appears_in_url': 'https://www.iea.org/reports/global-methane-tracker-2024', 'doc_id': 'iea_133', 'returned_content': 'https://www.iea.org/data-and-statistics/charts/main-sources-of-methane-emissions', 'source': 'IEA', 'sources': 'Methane emissions and abatement potential for oil, gas, and coal are based on the IEA (2023) Global Methane Tracker (https://www.iea.org/data-and-statistics/data-tools/methane-tracker-data-explorer) ; agriculture and waste is based on UNEP (2023), Global Methane Assessment (https://www.unep.org/resources/report/global-methane-assessment-benefits-and-costs-mitigating-methane-emissions). Emissions from biomass and bioenergy burning, which total around 10 Mt (https://essd.copernicus.org/articles/12/1561/2020/) of methane per year each, are not shown.', 'similarity_score': 0.6158384084701538, 'content': 'Main sources of methane emissions', 'reranking_score': 0.0806397795677185, 'query_used_for_retrieval': 'What are the main causes of global warming?', 'sources_used': ['IEA', 'OWID']}, page_content='Main sources of methane emissions'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_386', 'returned_content': '', 'source': 'OWID', 'subtitle': \"This is shown as a country or region's share of the global mean surface temperature change as a result of its cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change', 'similarity_score': 0.6807445883750916, 'content': 'Global warming: Contributions to the change in global mean surface temperature', 'reranking_score': 0.03409431874752045, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming: Contributions to the change in global mean surface temperature'),\n", " Document(metadata={'category': 'Climate Change', 'doc_id': 'owid_766', 'returned_content': '', 'source': 'OWID', 'subtitle': \"This is shown as a country or region's share of the global mean surface temperature change as a result of its cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change', 'similarity_score': 0.6807445883750916, 'content': 'Global warming: Contributions to the change in global mean surface temperature', 'reranking_score': 0.03409431874752045, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}, page_content='Global warming: Contributions to the change in global mean surface temperature'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_342', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Emissions factors quantify the average CO₂ output per unit of energy. They are measured in kilograms of CO₂ per megawatt-hour (MWh) of energy from various fossil fuel sources.', 'url': 'https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor', 'similarity_score': 0.6963810324668884, 'content': 'Carbon dioxide emissions factors', 'reranking_score': 0.007733839564025402, 'query_used_for_retrieval': 'What are the main causes of global warming?', 'sources_used': ['IEA', 'OWID']}, page_content='Carbon dioxide emissions factors'),\n", " Document(metadata={'category': 'Fossil Fuels', 'doc_id': 'owid_1408', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Emissions factors quantify the average CO₂ output per unit of energy. They are measured in kilograms of CO₂ per megawatt-hour (MWh) of energy from various fossil fuel sources.', 'url': 'https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor', 'similarity_score': 0.6963810324668884, 'content': 'Carbon dioxide emissions factors', 'reranking_score': 0.007733839564025402, 'query_used_for_retrieval': 'What are the main causes of global warming?', 'sources_used': ['IEA', 'OWID']}, page_content='Carbon dioxide emissions factors'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_359', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of carbon dioxide, methane, and nitrous oxide. This is for land use and agriculture only.\", 'url': 'https://ourworldindata.org/grapher/global-warming-land', 'similarity_score': 0.7010847330093384, 'content': 'Contribution to global mean surface temperature rise from agriculture and land use', 'reranking_score': 0.006090907845646143, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}, page_content='Contribution to global mean surface temperature rise from agriculture and land use'),\n", " Document(metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_387', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Greenhouse gas emissions include carbon dioxide, methane and nitrous oxide from all sources, including land-use change. They are measured in tonnes of carbon dioxide-equivalents over a 100-year timescale.', 'url': 'https://ourworldindata.org/grapher/total-ghg-emissions', 'similarity_score': 0.711588978767395, 'content': 'Greenhouse gas emissions', 'reranking_score': 0.001999091589823365, 'query_used_for_retrieval': 'What are the main causes of global warming?', 'sources_used': ['IEA', 'OWID']}, page_content='Greenhouse gas emissions')]" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from langchain_core.documents import Document\n", "\n", "graphs = [Document(page_content='Global warming contributions by gas and source', metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_383', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.', 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source', 'similarity_score': 0.5550143122673035, 'content': 'Global warming contributions by gas and source', 'reranking_score': 0.651607871055603, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Global warming contributions by gas and source', metadata={'category': 'Climate Change', 'doc_id': 'owid_764', 'returned_content': '', 'source': 'OWID', 'subtitle': 'The global mean surface temperature change as a result of the cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.', 'url': 'https://ourworldindata.org/grapher/global-warming-by-gas-and-source', 'similarity_score': 0.5550143122673035, 'content': 'Global warming contributions by gas and source', 'reranking_score': 0.651607871055603, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Global warming contributions from fossil fuels and land use', metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_384', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/warming-fossil-fuels-land-use', 'similarity_score': 0.6049439907073975, 'content': 'Global warming contributions from fossil fuels and land use', 'reranking_score': 0.22002366185188293, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Global warming contributions from fossil fuels and land use', metadata={'category': 'Climate Change', 'doc_id': 'owid_765', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/warming-fossil-fuels-land-use', 'similarity_score': 0.6049439907073975, 'content': 'Global warming contributions from fossil fuels and land use', 'reranking_score': 0.22002366185188293, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Main sources of methane emissions', metadata={'appears_in': 'Global Methane Tracker 2024', 'appears_in_url': 'https://www.iea.org/reports/global-methane-tracker-2024', 'doc_id': 'iea_133', 'returned_content': 'https://www.iea.org/data-and-statistics/charts/main-sources-of-methane-emissions', 'source': 'IEA', 'sources': 'Methane emissions and abatement potential for oil, gas, and coal are based on the IEA (2023) Global Methane Tracker (https://www.iea.org/data-and-statistics/data-tools/methane-tracker-data-explorer) ; agriculture and waste is based on UNEP (2023), Global Methane Assessment (https://www.unep.org/resources/report/global-methane-assessment-benefits-and-costs-mitigating-methane-emissions). Emissions from biomass and bioenergy burning, which total around 10 Mt (https://essd.copernicus.org/articles/12/1561/2020/) of methane per year each, are not shown.', 'similarity_score': 0.6158384084701538, 'content': 'Main sources of methane emissions', 'reranking_score': 0.0806397795677185, 'query_used_for_retrieval': 'What are the main causes of global warming?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Global warming: Contributions to the change in global mean surface temperature', metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_386', 'returned_content': '', 'source': 'OWID', 'subtitle': \"This is shown as a country or region's share of the global mean surface temperature change as a result of its cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change', 'similarity_score': 0.6807445883750916, 'content': 'Global warming: Contributions to the change in global mean surface temperature', 'reranking_score': 0.03409431874752045, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Global warming: Contributions to the change in global mean surface temperature', metadata={'category': 'Climate Change', 'doc_id': 'owid_766', 'returned_content': '', 'source': 'OWID', 'subtitle': \"This is shown as a country or region's share of the global mean surface temperature change as a result of its cumulative emissions of three gases – carbon dioxide, methane, and nitrous oxide.\", 'url': 'https://ourworldindata.org/grapher/contributions-global-temp-change', 'similarity_score': 0.6807445883750916, 'content': 'Global warming: Contributions to the change in global mean surface temperature', 'reranking_score': 0.03409431874752045, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Carbon dioxide emissions factors', metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_342', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Emissions factors quantify the average CO₂ output per unit of energy. They are measured in kilograms of CO₂ per megawatt-hour (MWh) of energy from various fossil fuel sources.', 'url': 'https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor', 'similarity_score': 0.6963810324668884, 'content': 'Carbon dioxide emissions factors', 'reranking_score': 0.007733839564025402, 'query_used_for_retrieval': 'What are the main causes of global warming?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Carbon dioxide emissions factors', metadata={'category': 'Fossil Fuels', 'doc_id': 'owid_1408', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Emissions factors quantify the average CO₂ output per unit of energy. They are measured in kilograms of CO₂ per megawatt-hour (MWh) of energy from various fossil fuel sources.', 'url': 'https://ourworldindata.org/grapher/carbon-dioxide-emissions-factor', 'similarity_score': 0.6963810324668884, 'content': 'Carbon dioxide emissions factors', 'reranking_score': 0.007733839564025402, 'query_used_for_retrieval': 'What are the main causes of global warming?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Contribution to global mean surface temperature rise from agriculture and land use', metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_359', 'returned_content': '', 'source': 'OWID', 'subtitle': \"The global mean surface temperature change as a result of a country or region's cumulative emissions of carbon dioxide, methane, and nitrous oxide. This is for land use and agriculture only.\", 'url': 'https://ourworldindata.org/grapher/global-warming-land', 'similarity_score': 0.7010847330093384, 'content': 'Contribution to global mean surface temperature rise from agriculture and land use', 'reranking_score': 0.006090907845646143, 'query_used_for_retrieval': 'How do human activities contribute to global warming?', 'sources_used': ['IEA', 'OWID']}), Document(page_content='Greenhouse gas emissions', metadata={'category': 'CO2 & Greenhouse Gas Emissions', 'doc_id': 'owid_387', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Greenhouse gas emissions include carbon dioxide, methane and nitrous oxide from all sources, including land-use change. They are measured in tonnes of carbon dioxide-equivalents over a 100-year timescale.', 'url': 'https://ourworldindata.org/grapher/total-ghg-emissions', 'similarity_score': 0.711588978767395, 'content': 'Greenhouse gas emissions', 'reranking_score': 0.001999091589823365, 'query_used_for_retrieval': 'What are the main causes of global warming?', 'sources_used': ['IEA', 'OWID']})]\n", "graphs" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[{'embedding': '',\n", " 'metadata': {'source': 'OWID',\n", " 'category': 'CO2 & Greenhouse Gas Emissions'}},\n", " {'embedding': '',\n", " 'metadata': {'source': 'OWID', 'category': 'Climate Change'}},\n", " {'embedding': '',\n", " 'metadata': {'source': 'OWID',\n", " 'category': 'CO2 & Greenhouse Gas Emissions'}},\n", " {'embedding': '',\n", " 'metadata': {'source': 'OWID', 'category': 'Climate Change'}},\n", " {'embedding': '',\n", " 'metadata': {'source': 'OWID',\n", " 'category': 'CO2 & Greenhouse Gas Emissions'}},\n", " {'embedding': '',\n", " 'metadata': {'source': 'OWID', 'category': 'Climate Change'}},\n", " {'embedding': '',\n", " 'metadata': {'source': 'OWID',\n", " 'category': 'CO2 & Greenhouse Gas Emissions'}},\n", " {'embedding': '',\n", " 'metadata': {'source': 'OWID', 'category': 'Fossil Fuels'}},\n", " {'embedding': '',\n", " 'metadata': {'source': 'OWID',\n", " 'category': 'CO2 & Greenhouse Gas Emissions'}},\n", " {'embedding': '',\n", " 'metadata': {'source': 'OWID',\n", " 'category': 'CO2 & Greenhouse Gas Emissions'}}]" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "graphs = [\n", " {\n", " \"embedding\": x.metadata[\"returned_content\"],\n", " \"metadata\": {\n", " \"source\": x.metadata[\"source\"],\n", " \"category\": x.metadata[\"category\"]\n", " }\n", " } for x in graphs if x.metadata[\"source\"] == \"OWID\"\n", " ]\n", "\n", "graphs" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [], "source": [ "from collections import defaultdict\n", "\n", "def generate_html(graphs):\n", " # Organize graphs by category\n", " categories = defaultdict(list)\n", " for graph in graphs:\n", " category = graph['metadata']['category']\n", " categories[category].append(graph['embedding'])\n", "\n", " # Begin constructing the HTML\n", " html_code = '''\n", "\n", "\n", "\n", " \n", " \n", " Graphs by Category\n", " \n", " \n", "\n", "\n", "
\n", "'''\n", "\n", " # Add buttons for each category\n", " for i, category in enumerate(categories.keys()):\n", " active_class = 'active' if i == 0 else ''\n", " html_code += f''\n", "\n", " html_code += '
'\n", "\n", " # Add content for each category\n", " for i, (category, embeds) in enumerate(categories.items()):\n", " active_class = 'active' if i == 0 else ''\n", " html_code += f'
'\n", " for embed in embeds:\n", " html_code += embed\n", " html_code += '
'\n", "\n", " html_code += '''\n", "\n", "\n", "'''\n", "\n", " return html_code\n" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'\\n\\n\\n\\n \\n \\n Graphs by Category\\n \\n \\n\\n\\n
\\n
\\n\\n\\n'" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "generate_html(graphs)" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Document(metadata={'category': 'Water Use & Stress', 'doc_id': 'owid_2184', 'returned_content': '', 'source': 'OWID', 'subtitle': 'Water quality is assessed by means of core physical and chemical parameters that reflect natural water quality. A water body is classified as \"good\" quality if at least 80% of monitoring values meet target quality levels.', 'url': 'https://ourworldindata.org/grapher/water-bodies-good-water-quality'}, page_content='Share of water bodies with good ambient water quality')" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vectorstore_graphs.similarity_search_with_relevance_scores(\"What is the trend of clean water?\")[0][0]" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['',\n", " '',\n", " '',\n", " '']" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "test_graphs = [x[0].metadata[\"returned_content\"] for x in vectorstore_graphs.similarity_search_with_relevance_scores(\"What is the trend of clean water?\")]\n", "test_graphs" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: GET https://api.gradio.app/pkg-version \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: GET http://127.0.0.1:7868/gradio_api/startup-events \"HTTP/1.1 200 OK\"\n", "INFO:httpx:HTTP Request: HEAD http://127.0.0.1:7868/ \"HTTP/1.1 200 OK\"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "* Running on local URL: http://127.0.0.1:7868\n", "\n", "To create a public link, set `share=True` in `launch()`.\n" ] }, { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# simple gradio\n", "import gradio as gr\n", "with gr.Blocks() as blocks:\n", " state_test = gr.State([])\n", " \n", " button = gr.Button(\"abc\")\n", " button.click(lambda : graphs, inputs = [], outputs = state_test)\n", " with gr.Column():\n", " # gr.HTML(generate_html(graphs), elem_id=\"graphs-placeholder\")\n", " gr.HTML(test_graphs)\n", " # gr.HTML(generate_html(state_test), elem_id=\"graphs-placeholder\")\n", "\n", "blocks.launch()\n", "\n", " " ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:sentence_transformers.SentenceTransformer:Use pytorch device_name: cpu\n", "INFO:sentence_transformers.SentenceTransformer:Load pretrained SentenceTransformer: BAAI/bge-base-en-v1.5\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Loading embeddings model: BAAI/bge-base-en-v1.5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/home/dora/anaconda3/envs/climateqa_huggingface/lib/python3.12/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", " warnings.warn(\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Loading FlashRankRanker model ms-marco-TinyBERT-L-2-v2\n", "Loading model FlashRank model ms-marco-TinyBERT-L-2-v2...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:chromadb.telemetry.posthog:Anonymized telemetry enabled. See https://docs.trychroma.com/telemetry for more information.\n" ] }, { "ename": "NameError", "evalue": "name 'make_graph_agent' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[18], line 10\u001b[0m\n\u001b[1;32m 7\u001b[0m vectorstore_graphs \u001b[38;5;241m=\u001b[39m Chroma(persist_directory\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/home/dora/climate-question-answering/data/vectorstore\u001b[39m\u001b[38;5;124m\"\u001b[39m, embedding_function\u001b[38;5;241m=\u001b[39membeddings_function)\n\u001b[1;32m 9\u001b[0m \u001b[38;5;66;03m# agent = make_graph_agent(llm,vectorstore,reranker)\u001b[39;00m\n\u001b[0;32m---> 10\u001b[0m agent \u001b[38;5;241m=\u001b[39m \u001b[43mmake_graph_agent\u001b[49m(llm\u001b[38;5;241m=\u001b[39mllm, vectorstore_ipcc\u001b[38;5;241m=\u001b[39mvectorstore, vectorstore_graphs\u001b[38;5;241m=\u001b[39mvectorstore_graphs, reranker\u001b[38;5;241m=\u001b[39mreranker)\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mchat\u001b[39m(query,history,audience,sources,reports):\n\u001b[1;32m 13\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"taking a query and a message history, use a pipeline (reformulation, retriever, answering) to yield a tuple of:\u001b[39;00m\n\u001b[1;32m 14\u001b[0m \u001b[38;5;124;03m (messages in gradio format, messages in langchain format, source documents)\"\"\"\u001b[39;00m\n", "\u001b[0;31mNameError\u001b[0m: name 'make_graph_agent' is not defined" ] } ], "source": [ "embeddings_function = get_embeddings_function()\n", "llm = get_llm(provider=\"openai\",max_tokens = 1024,temperature = 0.0)\n", "reranker = get_reranker(\"nano\")\n", "\n", "# Create vectorstore and retriever\n", "vectorstore = get_pinecone_vectorstore(embeddings_function)\n", "vectorstore_graphs = Chroma(persist_directory=f\"{ROOT_DIR}/data/vectorstore\", embedding_function=embeddings_function)\n", "\n", "# agent = make_graph_agent(llm,vectorstore,reranker)\n", "agent = make_graph_agent(llm=llm, vectorstore_ipcc=vectorstore, vectorstore_graphs=vectorstore_graphs, reranker=reranker)\n", "\n", "async def chat(query,history,audience,sources,reports):\n", " \"\"\"taking a query and a message history, use a pipeline (reformulation, retriever, answering) to yield a tuple of:\n", " (messages in gradio format, messages in langchain format, source documents)\"\"\"\n", "\n", " date_now = datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n", " print(f\">> NEW QUESTION ({date_now}) : {query}\")\n", "\n", " if audience == \"Children\":\n", " audience_prompt = audience_prompts[\"children\"]\n", " elif audience == \"General public\":\n", " audience_prompt = audience_prompts[\"general\"]\n", " elif audience == \"Experts\":\n", " audience_prompt = audience_prompts[\"experts\"]\n", " else:\n", " audience_prompt = audience_prompts[\"experts\"]\n", "\n", " # Prepare default values\n", " if len(sources) == 0:\n", " sources = [\"IPCC\"]\n", "\n", " if len(reports) == 0:\n", " reports = []\n", " \n", " inputs = {\"user_input\": query,\"audience\": audience_prompt,\"sources\":sources}\n", " print(f\"\\n\\nInputs:\\n {inputs}\\n\\n\")\n", " result = agent.astream_events(inputs,version = \"v1\") #{\"callbacks\":[MyCustomAsyncHandler()]})\n", " # result = rag_chain.stream(inputs)\n", "\n", " # path_reformulation = \"/logs/reformulation/final_output\"\n", " # path_keywords = \"/logs/keywords/final_output\"\n", " # path_retriever = \"/logs/find_documents/final_output\"\n", " # path_answer = \"/logs/answer/streamed_output_str/-\"\n", "\n", " docs = []\n", " graphs_html = \"\"\n", " docs_html = \"\"\n", " output_query = \"\"\n", " output_language = \"\"\n", " output_keywords = \"\"\n", " gallery = []\n", " updates = {}\n", " start_streaming = False\n", "\n", " steps_display = {\n", " \"categorize_intent\":(\"🔄️ Analyzing user message\",True),\n", " \"transform_query\":(\"🔄️ Thinking step by step to answer the question\",True),\n", " \"retrieve_documents\":(\"🔄️ Searching in the knowledge base\",False),\n", " }\n", "\n", " try:\n", " async for event in result:\n", "\n", " if event[\"event\"] == \"on_chat_model_stream\" and event[\"metadata\"][\"langgraph_node\"] in [\"answer_rag\", \"answer_chitchat\", \"answer_ai_impact\"]:\n", " if start_streaming == False:\n", " start_streaming = True\n", " history[-1] = (query,\"\")\n", "\n", " new_token = event[\"data\"][\"chunk\"].content\n", " # time.sleep(0.01)\n", " previous_answer = history[-1][1]\n", " previous_answer = previous_answer if previous_answer is not None else \"\"\n", " answer_yet = previous_answer + new_token\n", " answer_yet = parse_output_llm_with_sources(answer_yet)\n", " history[-1] = (query,answer_yet)\n", " \n", " elif event[\"name\"] == \"retrieve_documents\" and event[\"event\"] == \"on_chain_end\":\n", " try:\n", " docs = event[\"data\"][\"output\"][\"documents\"]\n", " docs_html = []\n", " for i, d in enumerate(docs, 1):\n", " docs_html.append(make_html_source(d, i))\n", " docs_html = \"\".join(docs_html)\n", "\n", " print(docs_html)\n", " except Exception as e:\n", " print(f\"Error getting documents: {e}\")\n", " print(event)\n", "\n", " # elif event[\"name\"] == \"retrieve_documents\" and event[\"event\"] == \"on_chain_start\":\n", " # print(event)\n", " # questions = event[\"data\"][\"input\"][\"questions\"]\n", " # questions = \"\\n\".join([f\"{i+1}. {q['question']} ({q['source']})\" for i,q in enumerate(questions)])\n", " # answer_yet = \"🔄️ Searching in the knowledge base\\n{questions}\"\n", " # history[-1] = (query,answer_yet)\n", "\n", " elif event[\"name\"] == \"retrieve_graphs\" and event[\"event\"] == \"on_chain_end\":\n", " try:\n", " recommended_content = event[\"data\"][\"output\"][\"recommended_content\"]\n", " graphs = [\n", " {\n", " \"embedding\": x.metadata[\"returned_content\"],\n", " \"metadata\": {\n", " \"source\": x.metadata[\"source\"],\n", " \"category\": x.metadata[\"category\"]\n", " }\n", " } for x in recommended_content if x.metadata[\"source\"] == \"OWID\"\n", " ]\n", " \n", " graphs_by_category = defaultdict(list)\n", " \n", " # Organize graphs by category\n", " for graph in graphs:\n", " category = graph['metadata']['category']\n", " graphs_by_category[category].append(graph['embedding']) \n", "\n", " \n", " for category, graphs in graphs_by_category.items():\n", " embeddings = \"\\n\".join(graphs)\n", " updates[graph_displays[category]] = embeddings\n", " \n", " print(f\"\\n\\nUpdates:\\n {updates}\\n\\n\")\n", " \n", " except Exception as e:\n", " print(f\"Error getting graphs: {e}\")\n", "\n", " for event_name,(event_description,display_output) in steps_display.items():\n", " if event[\"name\"] == event_name:\n", " if event[\"event\"] == \"on_chain_start\":\n", " # answer_yet = f\"

{event_description}

\"\n", " # answer_yet = make_toolbox(event_description, \"\", checked = False)\n", " answer_yet = event_description\n", " history[-1] = (query,answer_yet)\n", " # elif event[\"event\"] == \"on_chain_end\":\n", " # answer_yet = \"\"\n", " # history[-1] = (query,answer_yet)\n", " # if display_output:\n", " # print(event[\"data\"][\"output\"])\n", "\n", " # if op['path'] == path_reformulation: # reforulated question\n", " # try:\n", " # output_language = op['value'][\"language\"] # str\n", " # output_query = op[\"value\"][\"question\"]\n", " # except Exception as e:\n", " # raise gr.Error(f\"ClimateQ&A Error: {e} - The error has been noted, try another question and if the error remains, you can contact us :)\")\n", " \n", " # if op[\"path\"] == path_keywords:\n", " # try:\n", " # output_keywords = op['value'][\"keywords\"] # str\n", " # output_keywords = \" AND \".join(output_keywords)\n", " # except Exception as e:\n", " # pass\n", "\n", "\n", "\n", " history = [tuple(x) for x in history]\n", " yield history,docs_html,output_query,output_language,gallery,updates#,output_query,output_keywords\n", "\n", "\n", " except Exception as e:\n", " raise gr.Error(f\"{e}\")\n", "\n", "\n", " try:\n", " # Log answer on Azure Blob Storage\n", " if os.getenv(\"GRADIO_ENV\") != \"local\":\n", " timestamp = str(datetime.now().timestamp())\n", " file = timestamp + \".json\"\n", " prompt = history[-1][0]\n", " logs = {\n", " \"user_id\": str(user_id),\n", " \"prompt\": prompt,\n", " \"query\": prompt,\n", " \"question\":output_query,\n", " \"sources\":sources,\n", " \"docs\":serialize_docs(docs),\n", " \"answer\": history[-1][1],\n", " \"time\": timestamp,\n", " }\n", " log_on_azure(file, logs, share_client)\n", " except Exception as e:\n", " print(f\"Error logging on Azure Blob Storage: {e}\")\n", " raise gr.Error(f\"ClimateQ&A Error: {str(e)[:100]} - The error has been noted, try another question and if the error remains, you can contact us :)\")\n", "\n", " image_dict = {}\n", " for i,doc in enumerate(docs):\n", " \n", " if doc.metadata[\"chunk_type\"] == \"image\":\n", " try:\n", " key = f\"Image {i+1}\"\n", " image_path = doc.metadata[\"image_path\"].split(\"documents/\")[1]\n", " img = get_image_from_azure_blob_storage(image_path)\n", "\n", " # Convert the image to a byte buffer\n", " buffered = BytesIO()\n", " img.save(buffered, format=\"PNG\")\n", " img_str = base64.b64encode(buffered.getvalue()).decode()\n", "\n", " # Embedding the base64 string in Markdown\n", " markdown_image = f\"![Alt text](data:image/png;base64,{img_str})\"\n", " image_dict[key] = {\"img\":img,\"md\":markdown_image,\"caption\":doc.page_content,\"key\":key,\"figure_code\":doc.metadata[\"figure_code\"]}\n", " except Exception as e:\n", " print(f\"Skipped adding image {i} because of {e}\")\n", "\n", " if len(image_dict) > 0:\n", "\n", " gallery = [x[\"img\"] for x in list(image_dict.values())]\n", " img = list(image_dict.values())[0]\n", " img_md = img[\"md\"]\n", " img_caption = img[\"caption\"]\n", " img_code = img[\"figure_code\"]\n", " if img_code != \"N/A\":\n", " img_name = f\"{img['key']} - {img['figure_code']}\"\n", " else:\n", " img_name = f\"{img['key']}\"\n", "\n", " answer_yet = history[-1][1] + f\"\\n\\n{img_md}\\n

{img_name} - {img_caption}

\"\n", " history[-1] = (history[-1][0],answer_yet)\n", " history = [tuple(x) for x in history]\n", "\n", " print(f\"\\n\\nImages:\\n{gallery}\")\n", "\n", " # gallery = [x.metadata[\"image_path\"] for x in docs if (len(x.metadata[\"image_path\"]) > 0 and \"IAS\" in x.metadata[\"image_path\"])]\n", " # if len(gallery) > 0:\n", " # gallery = list(set(\"|\".join(gallery).split(\"|\")))\n", " # gallery = [get_image_from_azure_blob_storage(x) for x in gallery]\n", "\n", " yield history,docs_html,output_query,output_language,gallery,updates#,output_query,output_keywords\n" ] } ], "metadata": { "kernelspec": { "display_name": "climateqa", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.9" } }, "nbformat": 4, "nbformat_minor": 2 }